1. Describe your research scenario and questions(s).
A restaurant chain is changing its menu by adding a few new items.
The restaurant wantx to test three different marketing campaigns they
are thinking about using to promote their new menu items. The restaurant
wants to determine which promotion has the greatest effect on sales of
new menu items. The restaurant locations in which the campaigns will be
tested are selected at random. Each randomly selected location will
begin serving the new menu items, and run one of the three marketing
campaigns, also chosen at random. The weekly sales of the new menu items
are recorded for the first four weeks of the marketing campaign.
The restaurant chain is hiring a data scientist to evaluate the
effectiveness of three different marketing campaigns. The restaurant
wants to determine which of the three marketing strategies is most
effective at increasing sales of new menu items, so they can confidently
implement said marketing campaign at all their restaurant locations.
Research Question: Which marketing campaign(s)
results in the greatest increase in sales of new menu items for the
restaurant chain?
Many auxillary questions will be answered in our journey to answer
the above question, but the above question is the core, guiding inquiry
of our investigation.
2. Describe the data set.
Data Source: https://www.kaggle.com/datasets/chebotinaa/fast-food-marketing-campaign-ab-test?resource=download
# Input Data from csv file.
data = read.csv(file = "WA_Marketing-Campaign.csv", header = TRUE); data
# Factor the Data to make it easier to work with.
data$Promotion = factor(data$Promotion); data$Promotion
levels(data$Promotion)
data$week = factor(data$week)
levels(data$week)
tibble(data)
# Create Subsets for each Marketing Campaign to make our life easier.
promo_1 = filter(data, Promotion == 1); promo_1
promo_2 = filter(data, Promotion == 2); promo_2
promo_3 = filter(data, Promotion == 3); promo_3
# Data was luckily very clean, not a lot of data cleaning was necessary.
| MarketID |
Unique identifier for market. |
Range(1:10) |
| MarketSize |
Size of market area by sales |
Small, Medium, Large. |
| LocationID |
Unique identifier for store location |
|
| AgeOfStore |
Age of store in years |
|
| Promotion |
One of three promotions that were tested |
Range(1:3) |
| week |
One of four weeks when the promotions were run |
Range(1:4) |
| SalesInThousands |
Sales amount for a specific LocationID,
Promotion, and week |
|
SalesInThousands
Lets first look at the SalesInThousands
variable for each of the three marketing campaigns. The
SalesInThousands variable is the sales amount
in thousands of new menu items for a specific restaurant.
Exploratory Question: Are the sales of new menu
items similar for each marketing campaign group?
# Summary Statistics
# Mean
mean_1 = mean(promo_1$SalesInThousands); mean_1
mean_2 = mean(promo_2$SalesInThousands); mean_2
mean_3 = mean(promo_3$SalesInThousands); mean_3
mean_tot = mean(data$SalesInThousands); mean_tot
# Standard Deviation
std_1 = sd(promo_1$SalesInThousands); std_1
std_2 = sd(promo_2$SalesInThousands); std_2
std_3 = sd(promo_3$SalesInThousands); std_3
std_tot = sd(data$SalesInThousands); std_tot
# Number of Samples
n = nrow(data); n
k = length(levels(data$Promotion))
n_1 = nrow(promo_1); n_1
n_2 = nrow(promo_2); n_2
n_3 = nrow(promo_3); n_3
| Promo 1 |
58.10 |
16.55 |
172 |
| Promo 2 |
47.33 |
15.11 |
188 |
| Promo 3 |
55.36 |
16.77 |
188 |
| Total |
53.47 |
16.75 |
548 |
Table 1.0: Summary statistics for sales of new
menu items for all restaurants participating in the new marketing
campaigns.
The three different marketing campaigns subsets (Promotion 1,
Promotion 2, and Promotion 3) have very symmetric data, all having
similar means, standard deviations and population sizes seen in
Table 1.0. Lets create a boxplot to visualize this
symmetry.

Figure 1.0: Box plot showing the difference in
restaurant sales data for each of the three marketing campaigns.
Promotion 1 is in purple, Promotion 2 is in green, and Promotion 3 is in
yellow.
Promotion 1 has the highest mean sales of new menu items, followed by
Promotion 3 and then Promotion 2. All have similar variance, which is
important when comparing means. However, there seems to be more
Promotion 2 outliers. Lets see if that is true.
# Identify Outliers using IQR Methology
IQR = summary(promo_1$SalesInThousands)[5] - summary(promo_1$SalesInThousands)[2]; IQR
outliers = filter(promo_1, SalesInThousands > summary(promo_1$SalesInThousands)[5] + (1.5 * IQR) | SalesInThousands < summary(promo_1$SalesInThousands)[3] - (1.5 * IQR)); outliers$SalesInThousands
IQR = summary(promo_2$SalesInThousands)[5] - summary(promo_2$SalesInThousands)[2]; IQR
outliers_2 = filter(promo_2, SalesInThousands > summary(promo_2$SalesInThousands)[5] + (1.5 * IQR) | SalesInThousands < summary(promo_2$SalesInThousands)[3] - (1.5 * IQR)); outliers_2$SalesInThousands
IQR = summary(promo_3$SalesInThousands)[5] - summary(promo_3$SalesInThousands)[2]; IQR
outliers_3 = filter(promo_3, SalesInThousands > summary(promo_3$SalesInThousands)[5] + (1.5 * IQR) | SalesInThousands < summary(promo_3$SalesInThousands)[3] - (1.5 * IQR)); outliers_3$SalesInThousands
nrow(outliers)
nrow(outliers_2)
nrow(outliers_3)
Using the IQR methodology to identity outliers, we observed 12 sales
outliers each for both Promotion 1 and 2, and 30 sales outliers for
Promotion 3. This is an imbalance we should keep in mind and circle back
to before we make any final conclusions about our data.
To answer our exploratory question, the sales of new menu
items were in fact similar for each marketing campaign group but not the
same. Promotion 2 looks to deviate from Promotion 1 and
Promotion 2, and we will test to see if that deviation is
significant.
AgeOfStore
Lets next look at the AgeOfStore variable
for each of the three marketing campaigns. The
AgeOfStore variable is age of each restaurant
in the study.
Exploratory Question: Are age of restaurant
distributed different in each marketing campaign group?
Figure 2.0: Scatter plot showing the
relationship between AgeOfStore (x) and
SalesInThousands (y) for all restaurants conducting
marketing campaigns for new menu items. Double-click on the legend to
view individual marketing campaigns.
Looking at the scatter plot of age and sales for restaurants we
observe no clear linear relationship between the two variables. We can
confirm this with a calculation of the correlation coefficient, \(r\).
# Correlation Coefficient
cor(x=data$AgeOfStore, y=data$SalesInThousands)
Our the calculated correlation coefficient, \(r\), of store age and store sales is \(-0.029\), which is almost zero, meaning
there is little to no linear relationship between the two variables.
# Age Summary Statistic
tapply(data$AgeOfStore, data$Promotion, summary)
summary(promo_1$AgeOfStore)
sd(promo_1$AgeOfStore)
summary(promo_2$AgeOfStore)
sd(promo_2$AgeOfStore)
summary(promo_3$AgeOfStore)
sd(promo_3$AgeOfStore)
| Mean |
8.28 |
7.98 |
9.23 |
| Median |
6 |
7 |
8 |
| Standard Deviation |
6.64 |
6.60 |
6.65 |
| (Min, Max) |
(1, 27) |
(1, 28) |
(1, 24) |
| (Q1, Q3) |
(3, 12) |
(2, 10) |
(5, 12) |
Table 2.0: Summary statistics for store age for
all restaurants participating in the marketing campaign study.

Figure 3.0: Box plot showing the difference in
restaurant age data for each of the three marketing campaigns. Promotion
1 is in purple, Promotion 2 is in green, and Promotion 3 is in
yellow.
Both Table 2.0 and Figure
3.0 show that the age distributions among the three
marketing campaign is very similar. Promotion 1, 2 and 3 have a mean
ages of \(8.28\), \(7.98\), and \(9.23\) respectively and all have standard
deviations \(\sim 6.0\). All have some
clustering around age \(1\), and have
some outliers above Q3. All three marketing campaigns age distributions
are not identical but very similar for real world data standards. To
answer our exploratory question, the age of restaurant is not
distributed significantly different in each marketing
campaign.
MarketSize
Lets next look at the MarketSize variable
for each of the three marketing campaigns. The
MarketSize variable is a categorical variable
that describes the market size of each restaurant. There are three
market sizes: small, medium and large. The thresholds and criteria for
categorization are unknown.
Exploratory Question: Are market size proportions
similar in each marketing campaign group?
Figure 4.0: Stacked bar plot showing the
difference in total sales between marketing campaigns stratified by
market size.
For all three campaigns the greatest proportion of total sales can be
attributed to medium market restaurants, large market restaurants are
the next biggest contributor to total sale of new menu items, and small
market restaurants contributioned the least amount. The overall trend is
similar for all three marketing campaigns.
Figure 5.0: Stacked bar plot showing the
differences in amount of restaurant in each of the three market sizes
(small, medium, large) for each of the three marketing
campaigns.
Each marketing campaign has the most amount of medium market
restaurants followed by large market restaurants, and the least small
market restaurants. Promotion 1, Promotion 2, and Promotion 3 had \(56\), \(64\), and \(48\) large market restaurants respectively,
\(96\), \(108\), and \(116\) medium market restaurants
respectively, and \(20\), \(16\), and \(24\) small market restaurants respectively.
The overall trend is similar for all three marketing campaigns.
Lets consolidate these trends in Figure 4.0 and
Figure 5.0 into one scatter plot, to best visualize the
different amount of restaurants in each market size for each of the
three marketing campaigns, and how those markets contributed to the
marketing groups sales.
Figure 6.0: Scatter plot showing the
relationship between Mean Sales (x) and Restaurant Count (y) for all
restaurants conducting marketing campaigns for new menu items.
Additionally, if you hover over each point the Total Sales of each sub
group is listed.
The big take away from Figure 6.0 is that
Promotion 2 had the most large market restaurants, but the
lowest total large market sales (the total sales can be seen if
you hover over the data point in Figure 6.0). In
fact,all of Promotion 2’s restaurants, no matter the market size,
under-performed, but Promotion 2’s large market restaurants were the
most significant under-performing market for the Promotion 2 cohort.
Figure 6.0 identifies the reason Promotion 2 has the
lowest mean sales, but also shows that large market restaurants
under-performed more than Promotion 2’s small and medium market
restaurants.
Answering our exploratory question, the market size proportions were
similar for each marketing campaign group, and each market size
contributed proportionality based on their market size to the total
sales of the marketing campaign group. This trend is visualized in
Figure 6.0, which shows three clusters. a small market
cluster, a medium market cluster, and a large market cluster. The medium
market cluster had the lowest mean sales, while the large market had the
highest mean sales.
Week
Lastly, lets look at the Week variable for
each of the three marketing campaigns. The
Week variable ranges from week 1 through
week4, time stamping the four weeks of marketing campaign study. Sales
amounts for each restaurant were recorded for each of the four
weeks.
Exploratory Question: Are some campaigns trending
differently? Low sales in week 1, and higher in week 4?
Figure 7.0: Stacked bar plot showing the
difference in total sales between marketing campaigns and the four weeks
of the campaign.
There are no clear differences in marketing campaign performance week
to week for any of the three promotions. There are no visible trends
that shows an increase or decrease in marketing campaign performance
week by week for any promotion. Each promotions weekly performance from
week 1 through week 4 is consistent, each week accounting for about a
quarter of the monthly sales.
LS0tCnRpdGxlOiAiUmVzdGF1cmFudCBNYXJrZXRpbmcgQ2FtcGFpZ24gQS9CIFRlc3RpbmciCmF1dGhvcjogIkNvZHkgVGhheWVyICB8IERlY2VtYmVyIDE0LCAyMDIyIgpzdWJ0aXRsZTogIkNTNTU1IEZpbmFsIFByb2plY3QgKFByb2YuIEFsaXphZGVoLVNoYWJkaXosIEZhbGwgMjAyMikiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCjxici8+CgojIyMgUHJvamVjdCBGaWxlcwoKPiAqKkhUTUwgZmlsZSoqIGlzIHRoZSBtb3N0IHJlYWRhYmxlIGFuZCBoYXMgaW50cmFjdGFibGUgZ3JhcGhzLCBidXQgdGhlIHNvdXJjZSBjb2RlIG9mIGFsbCB0aGUgZmlndXJlcyBpcyBoaWRkZW4gZm9yIGNsYXJpdHkuCj4KPiAqKlJNRCBmaWxlKiogY29udGFpbnMgYWxsIHRoZSBzb3VyY2UgY29kZS4KPgo+ICoqUERGIGZpbGUqKiBpcyBqdXN0IGEgcGRmIHZlcnNpb24gb2YgdGhlIFJNRCBmaWxlLgoKYGBge3IgcmVzdWx0cz0iaGlkZSJ9CmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKYGBgCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ3JpZCkKbGlicmFyeShsYXR0aWNlKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShrYWJsZUV4dHJhKQpsaWJyYXJ5KEdHYWxseSkKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGVtbWVhbnMpCmxpYnJhcnkoY2FyKQoKCiMgQ29sb3JzCmNvbG9yc18zID0gYyh2aXJpZGlzKDI1KVs0XSwgdmlyaWRpcygyNSlbMTBdLCB2aXJpZGlzKDI1KVsxNV0sIHZpcmlkaXMoMjUpWzE5XSkKY29sb3JzXzQgPSBjKHZpcmlkaXMoMjUpWzFdLCB2aXJpZGlzKDI1KVs0XSwgdmlyaWRpcygyNSlbMTBdLCB2aXJpZGlzKDI1KVsxNV0sIHZpcmlkaXMoMjUpWzE5XSkKYGBgCgo8YnIvPgoKIyMgMS4gRGVzY3JpYmUgeW91ciByZXNlYXJjaCBzY2VuYXJpbyBhbmQgcXVlc3Rpb25zKHMpLgoKPGJyLz4KCkEgcmVzdGF1cmFudCBjaGFpbiBpcyBjaGFuZ2luZyBpdHMgbWVudSBieSBhZGRpbmcgYSBmZXcgbmV3IGl0ZW1zLiBUaGUgcmVzdGF1cmFudCB3YW50eCB0byB0ZXN0IHRocmVlIGRpZmZlcmVudCBtYXJrZXRpbmcgY2FtcGFpZ25zIHRoZXkgYXJlIHRoaW5raW5nIGFib3V0IHVzaW5nIHRvIHByb21vdGUgdGhlaXIgbmV3IG1lbnUgaXRlbXMuIFRoZSByZXN0YXVyYW50IHdhbnRzIHRvIGRldGVybWluZSB3aGljaCBwcm9tb3Rpb24gaGFzIHRoZSBncmVhdGVzdCBlZmZlY3Qgb24gc2FsZXMgb2YgbmV3IG1lbnUgaXRlbXMuIFRoZSByZXN0YXVyYW50IGxvY2F0aW9ucyBpbiB3aGljaCB0aGUgY2FtcGFpZ25zIHdpbGwgYmUgdGVzdGVkIGFyZSBzZWxlY3RlZCBhdCByYW5kb20uIEVhY2ggcmFuZG9tbHkgc2VsZWN0ZWQgbG9jYXRpb24gd2lsbCBiZWdpbiBzZXJ2aW5nIHRoZSBuZXcgbWVudSBpdGVtcywgYW5kIHJ1biBvbmUgb2YgdGhlIHRocmVlIG1hcmtldGluZyBjYW1wYWlnbnMsIGFsc28gY2hvc2VuIGF0IHJhbmRvbS4gVGhlIHdlZWtseSBzYWxlcyBvZiB0aGUgbmV3IG1lbnUgaXRlbXMgYXJlIHJlY29yZGVkIGZvciB0aGUgZmlyc3QgZm91ciB3ZWVrcyBvZiB0aGUgbWFya2V0aW5nIGNhbXBhaWduLgoKVGhlIHJlc3RhdXJhbnQgY2hhaW4gaXMgaGlyaW5nIGEgZGF0YSBzY2llbnRpc3QgdG8gZXZhbHVhdGUgdGhlIGVmZmVjdGl2ZW5lc3Mgb2YgdGhyZWUgZGlmZmVyZW50IG1hcmtldGluZyBjYW1wYWlnbnMuIFRoZSByZXN0YXVyYW50IHdhbnRzIHRvIGRldGVybWluZSB3aGljaCBvZiB0aGUgdGhyZWUgbWFya2V0aW5nIHN0cmF0ZWdpZXMgaXMgbW9zdCBlZmZlY3RpdmUgYXQgaW5jcmVhc2luZyBzYWxlcyBvZiBuZXcgbWVudSBpdGVtcywgc28gdGhleSBjYW4gY29uZmlkZW50bHkgaW1wbGVtZW50IHNhaWQgbWFya2V0aW5nIGNhbXBhaWduIGF0IGFsbCB0aGVpciByZXN0YXVyYW50IGxvY2F0aW9ucy4KCioqUmVzZWFyY2ggUXVlc3Rpb246KiogV2hpY2ggbWFya2V0aW5nIGNhbXBhaWduKHMpIHJlc3VsdHMgaW4gdGhlIGdyZWF0ZXN0IGluY3JlYXNlIGluIHNhbGVzIG9mIG5ldyBtZW51IGl0ZW1zIGZvciB0aGUgcmVzdGF1cmFudCBjaGFpbj8KCk1hbnkgYXV4aWxsYXJ5IHF1ZXN0aW9ucyB3aWxsIGJlIGFuc3dlcmVkIGluIG91ciBqb3VybmV5IHRvIGFuc3dlciB0aGUgYWJvdmUgcXVlc3Rpb24sIGJ1dCB0aGUgYWJvdmUgcXVlc3Rpb24gaXMgdGhlIGNvcmUsIGd1aWRpbmcgaW5xdWlyeSBvZiBvdXIgaW52ZXN0aWdhdGlvbi4KCjxici8+PGJyLz4KCiMjIDIuIERlc2NyaWJlIHRoZSBkYXRhIHNldC4gey50YWJzZXR9CgoqKkRhdGEgU291cmNlOioqIDxodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2NoZWJvdGluYWEvZmFzdC1mb29kLW1hcmtldGluZy1jYW1wYWlnbi1hYi10ZXN0P3Jlc291cmNlPWRvd25sb2FkPgoKYGBge3J9CiMgSW5wdXQgRGF0YSBmcm9tIGNzdiBmaWxlLgpkYXRhID0gcmVhZC5jc3YoZmlsZSA9ICJXQV9NYXJrZXRpbmctQ2FtcGFpZ24uY3N2IiwgaGVhZGVyID0gVFJVRSk7IGRhdGEKCiMgRmFjdG9yIHRoZSBEYXRhIHRvIG1ha2UgaXQgZWFzaWVyIHRvIHdvcmsgd2l0aC4KZGF0YSRQcm9tb3Rpb24gPSBmYWN0b3IoZGF0YSRQcm9tb3Rpb24pOyBkYXRhJFByb21vdGlvbgpsZXZlbHMoZGF0YSRQcm9tb3Rpb24pCmRhdGEkd2VlayA9IGZhY3RvcihkYXRhJHdlZWspCmxldmVscyhkYXRhJHdlZWspCnRpYmJsZShkYXRhKQoKIyBDcmVhdGUgU3Vic2V0cyBmb3IgZWFjaCBNYXJrZXRpbmcgQ2FtcGFpZ24gdG8gbWFrZSBvdXIgbGlmZSBlYXNpZXIuCnByb21vXzEgPSBmaWx0ZXIoZGF0YSwgUHJvbW90aW9uID09IDEpOyBwcm9tb18xCnByb21vXzIgPSBmaWx0ZXIoZGF0YSwgUHJvbW90aW9uID09IDIpOyBwcm9tb18yCnByb21vXzMgPSBmaWx0ZXIoZGF0YSwgUHJvbW90aW9uID09IDMpOyBwcm9tb18zCgojIERhdGEgd2FzIGx1Y2tpbHkgdmVyeSBjbGVhbiwgbm90IGEgbG90IG9mIGRhdGEgY2xlYW5pbmcgd2FzIG5lY2Vzc2FyeS4KYGBgCgpgYGB7cn0KcHJpbnQoZGF0YSkKYGBgCgo8YnIvPgoKfCAgICAgICAgICAgICAgICAgICAgICAgIHwgRGVzY3JpcHRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBWYWx1ZXMgICAgICAgICAgICAgICAgfAp8Oi0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLXwKfCAqKipNYXJrZXRJRCoqKiAgICAgICAgIHwgVW5pcXVlIGlkZW50aWZpZXIgZm9yIG1hcmtldC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBSYW5nZSgxOjEwKSAgICAgICAgICAgfAp8ICoqKk1hcmtldFNpemUqKiogICAgICAgfCBTaXplIG9mIG1hcmtldCBhcmVhIGJ5IHNhbGVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFNtYWxsLCBNZWRpdW0sIExhcmdlLiB8CnwgKioqTG9jYXRpb25JRCoqKiAgICAgICB8IFVuaXF1ZSBpZGVudGlmaWVyIGZvciBzdG9yZSBsb2NhdGlvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgIHwKfCAqKipBZ2VPZlN0b3JlKioqICAgICAgIHwgQWdlIG9mIHN0b3JlIGluIHllYXJzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgfAp8ICoqKlByb21vdGlvbioqKiAgICAgICAgfCBPbmUgb2YgdGhyZWUgcHJvbW90aW9ucyB0aGF0IHdlcmUgdGVzdGVkICAgICAgICAgICAgICAgICAgICAgICAgICB8IFJhbmdlKDE6MykgICAgICAgICAgICB8CnwgKioqd2VlayoqKiAgICAgICAgICAgICB8IE9uZSBvZiBmb3VyIHdlZWtzIHdoZW4gdGhlIHByb21vdGlvbnMgd2VyZSBydW4gICAgICAgICAgICAgICAgICAgIHwgUmFuZ2UoMTo0KSAgICAgICAgICAgIHwKfCAqKipTYWxlc0luVGhvdXNhbmRzKioqIHwgU2FsZXMgYW1vdW50IGZvciBhIHNwZWNpZmljICpMb2NhdGlvbklEKiwgKlByb21vdGlvbiosIGFuZCAqd2VlayogfCAgICAgICAgICAgICAgICAgICAgICAgfAoKPGJyLz4KCiMjIyAqKlNhbGVzSW5UaG91c2FuZHMqKgoKTGV0cyBmaXJzdCBsb29rIGF0IHRoZSAqKipTYWxlc0luVGhvdXNhbmRzKioqIHZhcmlhYmxlIGZvciBlYWNoIG9mIHRoZSB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ25zLiBUaGUgKioqU2FsZXNJblRob3VzYW5kcyoqKiB2YXJpYWJsZSBpcyB0aGUgc2FsZXMgYW1vdW50IGluIHRob3VzYW5kcyBvZiBuZXcgbWVudSBpdGVtcyBmb3IgYSBzcGVjaWZpYyByZXN0YXVyYW50LgoKKipFeHBsb3JhdG9yeSBRdWVzdGlvbjoqKiBBcmUgdGhlIHNhbGVzIG9mIG5ldyBtZW51IGl0ZW1zIHNpbWlsYXIgZm9yIGVhY2ggbWFya2V0aW5nIGNhbXBhaWduIGdyb3VwPwoKYGBge3J9CiMgU3VtbWFyeSBTdGF0aXN0aWNzCiMgTWVhbgptZWFuXzEgPSBtZWFuKHByb21vXzEkU2FsZXNJblRob3VzYW5kcyk7IG1lYW5fMQptZWFuXzIgPSBtZWFuKHByb21vXzIkU2FsZXNJblRob3VzYW5kcyk7IG1lYW5fMgptZWFuXzMgPSBtZWFuKHByb21vXzMkU2FsZXNJblRob3VzYW5kcyk7IG1lYW5fMwptZWFuX3RvdCA9IG1lYW4oZGF0YSRTYWxlc0luVGhvdXNhbmRzKTsgbWVhbl90b3QKCiMgU3RhbmRhcmQgRGV2aWF0aW9uCnN0ZF8xID0gc2QocHJvbW9fMSRTYWxlc0luVGhvdXNhbmRzKTsgc3RkXzEKc3RkXzIgPSBzZChwcm9tb18yJFNhbGVzSW5UaG91c2FuZHMpOyBzdGRfMgpzdGRfMyA9IHNkKHByb21vXzMkU2FsZXNJblRob3VzYW5kcyk7IHN0ZF8zCnN0ZF90b3QgPSBzZChkYXRhJFNhbGVzSW5UaG91c2FuZHMpOyBzdGRfdG90CgojIE51bWJlciBvZiBTYW1wbGVzCm4gPSBucm93KGRhdGEpOyBuCmsgPSBsZW5ndGgobGV2ZWxzKGRhdGEkUHJvbW90aW9uKSkKbl8xID0gbnJvdyhwcm9tb18xKTsgbl8xCm5fMiA9IG5yb3cocHJvbW9fMik7IG5fMgpuXzMgPSBucm93KHByb21vXzMpOyBuXzMKYGBgCgp8IE1hcmtldGluZyBDYW1wYWlnbiB8IFNhbGVzIChJbiBUaG91c2FuZHMpIHwgU3RhbmRhcmQgRGV2aWF0aW9uIHwgUG9wdWxhdGlvbiB8Cnw6LS0tLS0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tOnwKfCAgICAgIFByb21vIDEgICAgICAgfCAgICAgICAgNTguMTAgICAgICAgICB8ICAgICAgIDE2LjU1ICAgICAgICB8ICAgIDE3MiAgICAgfAp8ICAgICAgUHJvbW8gMiAgICAgICB8ICAgICAgICA0Ny4zMyAgICAgICAgIHwgICAgICAgMTUuMTEgICAgICAgIHwgICAgMTg4ICAgICB8CnwgICAgICBQcm9tbyAzICAgICAgIHwgICAgICAgIDU1LjM2ICAgICAgICAgfCAgICAgICAxNi43NyAgICAgICAgfCAgICAxODggICAgIHwKfCAgICAgKipUb3RhbCoqICAgICAgfCAgICAgICAgNTMuNDcgICAgICAgICB8ICAgICAgIDE2Ljc1ICAgICAgICB8ICAgIDU0OCAgICAgfAoKKioqVGFibGUgMS4wOioqIFN1bW1hcnkgc3RhdGlzdGljcyBmb3Igc2FsZXMgb2YgbmV3IG1lbnUgaXRlbXMgZm9yIGFsbCByZXN0YXVyYW50cyBwYXJ0aWNpcGF0aW5nIGluIHRoZSBuZXcgbWFya2V0aW5nIGNhbXBhaWducy4qCgo8YnIvPgoKVGhlIHRocmVlIGRpZmZlcmVudCBtYXJrZXRpbmcgY2FtcGFpZ25zIHN1YnNldHMgKFByb21vdGlvbiAxLCBQcm9tb3Rpb24gMiwgYW5kIFByb21vdGlvbiAzKSBoYXZlIHZlcnkgc3ltbWV0cmljIGRhdGEsIGFsbCBoYXZpbmcgc2ltaWxhciBtZWFucywgc3RhbmRhcmQgZGV2aWF0aW9ucyBhbmQgcG9wdWxhdGlvbiBzaXplcyBzZWVuIGluICoqVGFibGUgMS4wKiouIExldHMgY3JlYXRlIGEgYm94cGxvdCB0byB2aXN1YWxpemUgdGhpcyBzeW1tZXRyeS4KCmBgYHtyfQojIFNhbGVzIEJveHBsb3QKZGF0YV8yID0gZGF0YQpkYXRhXzIkUHJvbW90aW9uID0gYXMuY2hhcmFjdGVyKGRhdGFfMiRQcm9tb3Rpb24pCgpzYWxlc19wcm9tb19ib3ggPSBnZ3Bsb3QoZGF0YV8yLCBhZXMoeD1Qcm9tb3Rpb24sIHk9U2FsZXNJblRob3VzYW5kcywgZmlsbD1Qcm9tb3Rpb24pKSArIAogIHlsYWIoIlNhbGVzIChpbiB0aG91c2FuZHMpIikgKwogIHhsYWIoIk1hcmtldGluZyBDYW1wYWlnbiIpICsKICBnZW9tX2JveHBsb3QoKSArIGNvb3JkX2ZsaXAoKSArIAogIGdlb21fYm94cGxvdChjb2xvcj0iYmxhY2siKSArIAogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkgKwogIGdlb21fcG9pbnQoc2hhcGU9MTYsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcigwLjEpLCBjb2xvdXI9ImJsYWNrIiwgYWxwaGE9LjUwKSArCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG9yPSJncmF5OTAiKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShjb2xvcj0iZ3JheTk0IiksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmF5OTAiLCBzaXplID0wLjUpKSArCiAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGw9TkEsIGNvbG91ciA9ICJncmF5OTAiLCBzaXplID0gMC41LCBsaW5ldHlwZSA9ICJzb2xpZCIpKSArIAogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoY29sb3I9ImdyYXk5MCIsIHNpemU9MC41KSkgKyAKICB0aGVtZShheGlzLnRpY2tzLmxlbmd0aCA9IHVuaXQoMC4xOCwgImNtIikpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCnNhbGVzX3Byb21vX2JveApgYGAKCioqKkZpZ3VyZSAxLjA6KiogQm94IHBsb3Qgc2hvd2luZyB0aGUgZGlmZmVyZW5jZSBpbiByZXN0YXVyYW50IHNhbGVzIGRhdGEgZm9yIGVhY2ggb2YgdGhlIHRocmVlIG1hcmtldGluZyBjYW1wYWlnbnMuIFByb21vdGlvbiAxIGlzIGluIHB1cnBsZSwgUHJvbW90aW9uIDIgaXMgaW4gZ3JlZW4sIGFuZCBQcm9tb3Rpb24gMyBpcyBpbiB5ZWxsb3cuKgoKPGJyLz4KClByb21vdGlvbiAxIGhhcyB0aGUgaGlnaGVzdCBtZWFuIHNhbGVzIG9mIG5ldyBtZW51IGl0ZW1zLCBmb2xsb3dlZCBieSBQcm9tb3Rpb24gMyBhbmQgdGhlbiBQcm9tb3Rpb24gMi4gQWxsIGhhdmUgc2ltaWxhciB2YXJpYW5jZSwgd2hpY2ggaXMgaW1wb3J0YW50IHdoZW4gY29tcGFyaW5nIG1lYW5zLiBIb3dldmVyLCB0aGVyZSBzZWVtcyB0byBiZSBtb3JlIFByb21vdGlvbiAyIG91dGxpZXJzLiBMZXRzIHNlZSBpZiB0aGF0IGlzIHRydWUuCgpgYGB7cn0KIyBJZGVudGlmeSBPdXRsaWVycyB1c2luZyBJUVIgTWV0aG9sb2d5CgpJUVIgPSBzdW1tYXJ5KHByb21vXzEkU2FsZXNJblRob3VzYW5kcylbNV0gLSBzdW1tYXJ5KHByb21vXzEkU2FsZXNJblRob3VzYW5kcylbMl07IElRUgpvdXRsaWVycyA9IGZpbHRlcihwcm9tb18xLCBTYWxlc0luVGhvdXNhbmRzID4gc3VtbWFyeShwcm9tb18xJFNhbGVzSW5UaG91c2FuZHMpWzVdICsgKDEuNSAqIElRUikgfCBTYWxlc0luVGhvdXNhbmRzIDwgc3VtbWFyeShwcm9tb18xJFNhbGVzSW5UaG91c2FuZHMpWzNdIC0gKDEuNSAqIElRUikpOyBvdXRsaWVycyRTYWxlc0luVGhvdXNhbmRzCgpJUVIgPSBzdW1tYXJ5KHByb21vXzIkU2FsZXNJblRob3VzYW5kcylbNV0gLSBzdW1tYXJ5KHByb21vXzIkU2FsZXNJblRob3VzYW5kcylbMl07IElRUgpvdXRsaWVyc18yID0gZmlsdGVyKHByb21vXzIsIFNhbGVzSW5UaG91c2FuZHMgPiBzdW1tYXJ5KHByb21vXzIkU2FsZXNJblRob3VzYW5kcylbNV0gKyAoMS41ICogSVFSKSB8IFNhbGVzSW5UaG91c2FuZHMgPCBzdW1tYXJ5KHByb21vXzIkU2FsZXNJblRob3VzYW5kcylbM10gLSAoMS41ICogSVFSKSk7IG91dGxpZXJzXzIkU2FsZXNJblRob3VzYW5kcwoKSVFSID0gc3VtbWFyeShwcm9tb18zJFNhbGVzSW5UaG91c2FuZHMpWzVdIC0gc3VtbWFyeShwcm9tb18zJFNhbGVzSW5UaG91c2FuZHMpWzJdOyBJUVIKb3V0bGllcnNfMyA9IGZpbHRlcihwcm9tb18zLCBTYWxlc0luVGhvdXNhbmRzID4gc3VtbWFyeShwcm9tb18zJFNhbGVzSW5UaG91c2FuZHMpWzVdICsgKDEuNSAqIElRUikgfCBTYWxlc0luVGhvdXNhbmRzIDwgc3VtbWFyeShwcm9tb18zJFNhbGVzSW5UaG91c2FuZHMpWzNdIC0gKDEuNSAqIElRUikpOyBvdXRsaWVyc18zJFNhbGVzSW5UaG91c2FuZHMKCm5yb3cob3V0bGllcnMpCm5yb3cob3V0bGllcnNfMikKbnJvdyhvdXRsaWVyc18zKQpgYGAKClVzaW5nIHRoZSBJUVIgbWV0aG9kb2xvZ3kgdG8gaWRlbnRpdHkgb3V0bGllcnMsIHdlIG9ic2VydmVkIDEyIHNhbGVzIG91dGxpZXJzIGVhY2ggZm9yIGJvdGggUHJvbW90aW9uIDEgYW5kIDIsIGFuZCAzMCBzYWxlcyBvdXRsaWVycyBmb3IgUHJvbW90aW9uIDMuIFRoaXMgaXMgYW4gaW1iYWxhbmNlIHdlIHNob3VsZCBrZWVwIGluIG1pbmQgYW5kIGNpcmNsZSBiYWNrIHRvIGJlZm9yZSB3ZSBtYWtlIGFueSBmaW5hbCBjb25jbHVzaW9ucyBhYm91dCBvdXIgZGF0YS4KClRvIGFuc3dlciBvdXIgZXhwbG9yYXRvcnkgcXVlc3Rpb24sICoqdGhlIHNhbGVzIG9mIG5ldyBtZW51IGl0ZW1zIHdlcmUgaW4gZmFjdCBzaW1pbGFyIGZvciBlYWNoIG1hcmtldGluZyBjYW1wYWlnbiBncm91cCBidXQgbm90IHRoZSBzYW1lLioqIFByb21vdGlvbiAyIGxvb2tzIHRvIGRldmlhdGUgZnJvbSBQcm9tb3Rpb24gMSBhbmQgUHJvbW90aW9uIDIsIGFuZCB3ZSB3aWxsIHRlc3QgdG8gc2VlIGlmIHRoYXQgZGV2aWF0aW9uIGlzIHNpZ25pZmljYW50LgoKPGJyLz4KCiMjIyAqKkFnZU9mU3RvcmUqKgoKTGV0cyBuZXh0IGxvb2sgYXQgdGhlICoqKkFnZU9mU3RvcmUqKiogdmFyaWFibGUgZm9yIGVhY2ggb2YgdGhlIHRocmVlIG1hcmtldGluZyBjYW1wYWlnbnMuIFRoZSAqKipBZ2VPZlN0b3JlKioqIHZhcmlhYmxlIGlzIGFnZSBvZiBlYWNoIHJlc3RhdXJhbnQgaW4gdGhlIHN0dWR5LgoKKipFeHBsb3JhdG9yeSBRdWVzdGlvbjoqKiBBcmUgYWdlIG9mIHJlc3RhdXJhbnQgZGlzdHJpYnV0ZWQgZGlmZmVyZW50IGluIGVhY2ggbWFya2V0aW5nIGNhbXBhaWduIGdyb3VwPwoKYGBge3IgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NSwgZmlnLmZ1bGx3aWR0aD1UUlVFfQoKIyBTY2F0dGVyIFBsb3QgQWdlIHZzLiBTYWxlcwp4ID0gZGF0YSRTYWxlc0luVGhvdXNhbmRzCnkgPSBkYXRhJEFnZU9mU3RvcmUKCmFnZV9zYWxlc19zY2F0dGVyID0gcGxvdF9seShkYXRhLCB5ID0gflNhbGVzSW5UaG91c2FuZHMsIHggPSB+QWdlT2ZTdG9yZSwgY29sb3IgPSB+UHJvbW90aW9uLCBjb2xvcnMgPSBjb2xvcnNfMywKICAgICAgICB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ21hcmtlcnMnLAogICAgICAgIG1hcmtlciA9IGxpc3Qoc3ltYm9sID0gJ2NpcmNsZScsIHNpemVtb2RlID0gJ2RpYW1ldGVyJywKICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaXN0KHdpZHRoID0gMSwgY29sb3IgPSAnYmxhY2snKSkpICU+JQpsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0FnZSBvZiBSZXN0YXVyYW50JywKICAgICAgICAgICAgICAgICAgICByYW5nZSA9IGMobWluKHgpIC0gbWVhbih4KS9ucm93KHgpLCBtYXgoeCkgKyBtZWFuKHgpL25yb3coeCkpLAogICAgICAgICAgICAgICAgICAgIHplcm9saW5ld2lkdGggPSAyLAogICAgICAgICAgICAgICAgICAgIHRpY2t3aWR0aCA9IDEuNSwKICAgICAgICAgICAgICAgICAgICB0aWNrbGVuID0gNSwKICAgICAgICAgICAgICAgICAgICB0aWNrcHJlZml4PSIiLAogICAgICAgICAgICAgICAgICAgIGdyaWR3aWR0aCA9IDEpLAogICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gJ1NhbGVzIChpbiB0aG91c2FuZHMpJywKICAgICAgICAgICAgICAgICAgICByYW5nZSA9IGMobWluKHkpIC0gbWVhbih5KS9ucm93KHkpLCBtYXgoeSkpICsgbWVhbih5KS9ucm93KHkpLAogICAgICAgICAgICAgICAgICAgIHplcm9saW5ld2lkdGggPSAyLAogICAgICAgICAgICAgICAgICAgIHRpY2t3aWR0aCA9IDEuNSwKICAgICAgICAgICAgICAgICAgICB0aWNrbGVuID0gNSwKICAgICAgICAgICAgICAgICAgICBncmlkd2l0aCA9IDEpKQoKYWdlX3NhbGVzX3NjYXR0ZXIKYGBgCgoqKipGaWd1cmUgMi4wOioqIFNjYXR0ZXIgcGxvdCBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiAqKkFnZU9mU3RvcmUqKiAoeCkgYW5kICoqU2FsZXNJblRob3VzYW5kcyoqICh5KSBmb3IgYWxsIHJlc3RhdXJhbnRzIGNvbmR1Y3RpbmcgbWFya2V0aW5nIGNhbXBhaWducyBmb3IgbmV3IG1lbnUgaXRlbXMuIERvdWJsZS1jbGljayBvbiB0aGUgbGVnZW5kIHRvIHZpZXcgaW5kaXZpZHVhbCBtYXJrZXRpbmcgY2FtcGFpZ25zLioKCjxici8+CgpMb29raW5nIGF0IHRoZSBzY2F0dGVyIHBsb3Qgb2YgYWdlIGFuZCBzYWxlcyBmb3IgcmVzdGF1cmFudHMgd2Ugb2JzZXJ2ZSBubyBjbGVhciBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHR3byB2YXJpYWJsZXMuIFdlIGNhbiBjb25maXJtIHRoaXMgd2l0aCBhIGNhbGN1bGF0aW9uIG9mIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCwgJHIkLgoKYGBge3J9CiMgQ29ycmVsYXRpb24gQ29lZmZpY2llbnQKY29yKHg9ZGF0YSRBZ2VPZlN0b3JlLCB5PWRhdGEkU2FsZXNJblRob3VzYW5kcykKYGBgCgpPdXIgdGhlIGNhbGN1bGF0ZWQgY29ycmVsYXRpb24gY29lZmZpY2llbnQsICRyJCwgb2Ygc3RvcmUgYWdlIGFuZCBzdG9yZSBzYWxlcyBpcyAkLTAuMDI5JCwgd2hpY2ggaXMgYWxtb3N0IHplcm8sIG1lYW5pbmcgdGhlcmUgaXMgbGl0dGxlIHRvIG5vIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHdvIHZhcmlhYmxlcy4KCmBgYHtyfQojIEFnZSBTdW1tYXJ5IFN0YXRpc3RpYwp0YXBwbHkoZGF0YSRBZ2VPZlN0b3JlLCBkYXRhJFByb21vdGlvbiwgc3VtbWFyeSkKCnN1bW1hcnkocHJvbW9fMSRBZ2VPZlN0b3JlKQpzZChwcm9tb18xJEFnZU9mU3RvcmUpCnN1bW1hcnkocHJvbW9fMiRBZ2VPZlN0b3JlKQpzZChwcm9tb18yJEFnZU9mU3RvcmUpCnN1bW1hcnkocHJvbW9fMyRBZ2VPZlN0b3JlKQpzZChwcm9tb18zJEFnZU9mU3RvcmUpCmBgYAoKfCAgICAgICAgICAgICAgICAgICAgICAgIHwgKipQcm9tbyAxKiogfCAqKlByb21vIDIqKiB8ICoqUHJvbW8gMyoqIHwKfDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tOnwKfCAgICAgICAgKipNZWFuKiogICAgICAgIHwgICAgOC4yOCAgICAgfCAgICA3Ljk4ICAgICB8ICAgIDkuMjMgICAgIHwKfCAgICAgICAqKk1lZGlhbioqICAgICAgIHwgICAgICA2ICAgICAgfCAgICAgIDcgICAgICB8ICAgICAgOCAgICAgIHwKfCAqKlN0YW5kYXJkIERldmlhdGlvbioqIHwgICAgNi42NCAgICAgfCAgICA2LjYwICAgICB8ICAgIDYuNjUgICAgIHwKfCAgICAgKiooTWluLCBNYXgpKiogICAgIHwgICAoMSwgMjcpICAgfCAgICgxLCAyOCkgICB8ICAgKDEsIDI0KSAgIHwKfCAgICAgICoqKFExLCBRMykqKiAgICAgIHwgICAoMywgMTIpICAgfCAgICgyLCAxMCkgICB8ICAgKDUsIDEyKSAgIHwKCioqKlRhYmxlIDIuMDoqKiBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0b3JlIGFnZSBmb3IgYWxsIHJlc3RhdXJhbnRzIHBhcnRpY2lwYXRpbmcgaW4gdGhlIG1hcmtldGluZyBjYW1wYWlnbiBzdHVkeS4qCgo8YnIvPgoKYGBge3J9CgojIEFnZSBCb3hwbG90CmRhdGFfMiA9IGRhdGEKZGF0YV8yJFByb21vdGlvbiA9IGFzLmNoYXJhY3RlcihkYXRhXzIkUHJvbW90aW9uKQoKYWdlX3Byb21vX2JveCA9IGdncGxvdChkYXRhXzIsIGFlcyh4PVByb21vdGlvbiwgeT1BZ2VPZlN0b3JlLCBmaWxsPVByb21vdGlvbikpICsgCiAgeWxhYigiQWdlIG9mIFJlc3RhdXJhbnQiKSArCiAgeGxhYigiTWFya2V0aW5nIENhbXBhaWduIikgKwogIGdlb21fYm94cGxvdCgpICsgY29vcmRfZmxpcCgpICsgCiAgZ2VvbV9ib3hwbG90KGNvbG9yPSJibGFjayIpICsgCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoKSArCiAgZ2VvbV9wb2ludChzaGFwZT0xNiwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKDAuMSksIGNvbG91cj0iYmxhY2siLCBhbHBoYT0uNTApICsKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3I9ImdyYXk5MCIpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG9yPSJncmF5OTQiKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImdyYXk5MCIsIHNpemUgPTAuNSkpICsKICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbD1OQSwgY29sb3VyID0gImdyYXk5MCIsIHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIikpICsgCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShjb2xvcj0iZ3JheTkwIiwgc2l6ZT0wLjUpKSArIAogIHRoZW1lKGF4aXMudGlja3MubGVuZ3RoID0gdW5pdCgwLjE4LCAiY20iKSkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKYWdlX3Byb21vX2JveApgYGAKCioqKkZpZ3VyZSAzLjA6KiogQm94IHBsb3Qgc2hvd2luZyB0aGUgZGlmZmVyZW5jZSBpbiByZXN0YXVyYW50IGFnZSBkYXRhIGZvciBlYWNoIG9mIHRoZSB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ25zLiBQcm9tb3Rpb24gMSBpcyBpbiBwdXJwbGUsIFByb21vdGlvbiAyIGlzIGluIGdyZWVuLCBhbmQgUHJvbW90aW9uIDMgaXMgaW4geWVsbG93LioKCjxici8+CgpCb3RoICoqVGFibGUgMi4wKiogYW5kICoqRmlndXJlKiogKiozLjAqKiBzaG93IHRoYXQgdGhlIGFnZSBkaXN0cmlidXRpb25zIGFtb25nIHRoZSB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ24gaXMgdmVyeSBzaW1pbGFyLiBQcm9tb3Rpb24gMSwgMiBhbmQgMyBoYXZlIGEgbWVhbiBhZ2VzIG9mICQ4LjI4JCwgJDcuOTgkLCBhbmQgJDkuMjMkIHJlc3BlY3RpdmVseSBhbmQgYWxsIGhhdmUgc3RhbmRhcmQgZGV2aWF0aW9ucyAkXHNpbSA2LjAkLiBBbGwgaGF2ZSBzb21lIGNsdXN0ZXJpbmcgYXJvdW5kIGFnZSAkMSQsIGFuZCBoYXZlIHNvbWUgb3V0bGllcnMgYWJvdmUgUTMuIEFsbCB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ25zIGFnZSBkaXN0cmlidXRpb25zIGFyZSBub3QgaWRlbnRpY2FsIGJ1dCB2ZXJ5IHNpbWlsYXIgZm9yIHJlYWwgd29ybGQgZGF0YSBzdGFuZGFyZHMuIFRvIGFuc3dlciBvdXIgZXhwbG9yYXRvcnkgcXVlc3Rpb24sICoqdGhlIGFnZSBvZiByZXN0YXVyYW50IGlzIG5vdCBkaXN0cmlidXRlZCBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBpbiBlYWNoIG1hcmtldGluZyBjYW1wYWlnbi4qKgoKPGJyLz4KCiMjIyAqKk1hcmtldFNpemUqKgoKTGV0cyBuZXh0IGxvb2sgYXQgdGhlICoqKk1hcmtldFNpemUqKiogdmFyaWFibGUgZm9yIGVhY2ggb2YgdGhlIHRocmVlIG1hcmtldGluZyBjYW1wYWlnbnMuIFRoZSAqKipNYXJrZXRTaXplKioqIHZhcmlhYmxlIGlzIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgdGhhdCBkZXNjcmliZXMgdGhlIG1hcmtldCBzaXplIG9mIGVhY2ggcmVzdGF1cmFudC4gVGhlcmUgYXJlIHRocmVlIG1hcmtldCBzaXplczogc21hbGwsIG1lZGl1bSBhbmQgbGFyZ2UuIFRoZSB0aHJlc2hvbGRzIGFuZCBjcml0ZXJpYSBmb3IgY2F0ZWdvcml6YXRpb24gYXJlIHVua25vd24uCgoqKkV4cGxvcmF0b3J5IFF1ZXN0aW9uOioqIEFyZSBtYXJrZXQgc2l6ZSBwcm9wb3J0aW9ucyBzaW1pbGFyIGluIGVhY2ggbWFya2V0aW5nIGNhbXBhaWduIGdyb3VwPwoKYGBge3IgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NCwgZmlnLmZ1bGx3aWR0aD1UUlVFfQojIFN0YWNrIEJhciBQbG90IChUb3RhbCBTYWxlcykKbWFya2V0X2JhciA9IHBsb3RfbHkoZGF0YSwgeT1+UHJvbW90aW9uLCB4PX5TYWxlc0luVGhvdXNhbmRzLCBjb2xvcj1+TWFya2V0U2l6ZSwgY29sb3JzID0gY29sb3JzXzQsIHR5cGUgPSAiYmFyIikgJT4lCiAgbGF5b3V0KGJhcm1vZGU9InN0YWNrIikgJT4lCiAgbGF5b3V0KHlheGlzID0gbGlzdCh0aXRsZT0iTWFya2V0aW5nIENhbXBhaWduIiwgY2F0ZWdvcnlvcmRlciA9ICJhcnJheSIsIGNhdGVnb3J5YXJyYXkgPSBkYXRhJFByb21vdGlvbiwgCiAgICAgICAgICAgICAgICAgICAgICBsaW5lY29sb3IgPSAid2hpdGUiKSkgJT4lCiAgbGF5b3V0KHlheGlzID0gbGlzdChtaW5vciA9IGxpc3Qoc2hvd2dyaWQgPSBGQUxTRSkpKSAlPiUKICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlPSJUb3RhbCBTYWxlcyAoaW4gdGhvdXNhbmRzKSIpLCBsZWdlbmQgPSBsaXN0KHRpdGxlPWxpc3QodGV4dD0nTWFya2V0IFNpemUnKSkpCgptYXJrZXRfYmFyCmBgYAoKKioqRmlndXJlIDQuMDoqKiBTdGFja2VkIGJhciBwbG90IHNob3dpbmcgdGhlIGRpZmZlcmVuY2UgaW4gdG90YWwgc2FsZXMgYmV0d2VlbiBtYXJrZXRpbmcgY2FtcGFpZ25zIHN0cmF0aWZpZWQgYnkgbWFya2V0IHNpemUuKgoKPGJyLz4KCkZvciBhbGwgdGhyZWUgY2FtcGFpZ25zIHRoZSBncmVhdGVzdCBwcm9wb3J0aW9uIG9mIHRvdGFsIHNhbGVzIGNhbiBiZSBhdHRyaWJ1dGVkIHRvIG1lZGl1bSBtYXJrZXQgcmVzdGF1cmFudHMsIGxhcmdlIG1hcmtldCByZXN0YXVyYW50cyBhcmUgdGhlIG5leHQgYmlnZ2VzdCBjb250cmlidXRvciB0byB0b3RhbCBzYWxlIG9mIG5ldyBtZW51IGl0ZW1zLCBhbmQgc21hbGwgbWFya2V0IHJlc3RhdXJhbnRzIGNvbnRyaWJ1dGlvbmVkIHRoZSBsZWFzdCBhbW91bnQuIFRoZSBvdmVyYWxsIHRyZW5kIGlzIHNpbWlsYXIgZm9yIGFsbCB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ25zLgoKYGBge3IgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NCwgZmlnLmZ1bGx3aWR0aD1UUlVFfQojIFN0YWNrIEJhciBQbG90IChDb3VudCkKbWFya2V0X2RhdGEgPSAgZGF0YSAlPiUKZ3JvdXBfYnkoUHJvbW90aW9uLCBNYXJrZXRTaXplKSAlPiUKc3VtbWFyaXplKENvdW50PW4oKSwgc2FsZXNfbWVhbj1tZWFuKFNhbGVzSW5UaG91c2FuZHMpLCBzYWxlc190b3RhbD1zdW0oU2FsZXNJblRob3VzYW5kcykpCgojdmlzdWFsaXppbmcgZGF0YQptYXJrZXRfY291bnRfYmFyID0gcGxvdF9seShtYXJrZXRfZGF0YSwgeT1+UHJvbW90aW9uLCB4PX5Db3VudCwgY29sb3I9fk1hcmtldFNpemUsIGNvbG9ycyA9IGNvbG9yc180LCB0eXBlID0gImJhciIpICU+JQogIGxheW91dChiYXJtb2RlPSJzdGFjayIpICU+JQogIGxheW91dCh5YXhpcyA9IGxpc3QodGl0bGU9Ik1hcmtldGluZyBDYW1wYWlnbiIsIGNhdGVnb3J5b3JkZXIgPSAiYXJyYXkiLCBjYXRlZ29yeWFycmF5ID0gZGF0YSRQcm9tb3Rpb24sIAogICAgICAgICAgICAgICAgICAgICAgbGluZWNvbG9yID0gIndoaXRlIikpICU+JQogIGxheW91dCh5YXhpcyA9IGxpc3QobWlub3IgPSBsaXN0KHNob3dncmlkID0gRkFMU0UpKSkgJT4lCiAgbGF5b3V0KHhheGlzID0gbGlzdCh0aXRsZT0iUmVzdGF1cmFudCBDb3VudCIpLCBsZWdlbmQgPSBsaXN0KHRpdGxlPWxpc3QodGV4dD0nTWFya2V0IFNpemUnKSkpCgptYXJrZXRfY291bnRfYmFyCmBgYAoKKioqRmlndXJlIDUuMDoqKiBTdGFja2VkIGJhciBwbG90IHNob3dpbmcgdGhlIGRpZmZlcmVuY2VzIGluIGFtb3VudCBvZiByZXN0YXVyYW50IGluIGVhY2ggb2YgdGhlIHRocmVlIG1hcmtldCBzaXplcyAoc21hbGwsIG1lZGl1bSwgbGFyZ2UpIGZvciBlYWNoIG9mIHRoZSB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ25zLioKCjxici8+CgpFYWNoIG1hcmtldGluZyBjYW1wYWlnbiBoYXMgdGhlIG1vc3QgYW1vdW50IG9mIG1lZGl1bSBtYXJrZXQgcmVzdGF1cmFudHMgZm9sbG93ZWQgYnkgbGFyZ2UgbWFya2V0IHJlc3RhdXJhbnRzLCBhbmQgdGhlIGxlYXN0IHNtYWxsIG1hcmtldCByZXN0YXVyYW50cy4gUHJvbW90aW9uIDEsIFByb21vdGlvbiAyLCBhbmQgUHJvbW90aW9uIDMgaGFkICQ1NiQsICQ2NCQsIGFuZCAkNDgkIGxhcmdlIG1hcmtldCByZXN0YXVyYW50cyByZXNwZWN0aXZlbHksICQ5NiQsICQxMDgkLCBhbmQgJDExNiQgbWVkaXVtIG1hcmtldCByZXN0YXVyYW50cyByZXNwZWN0aXZlbHksIGFuZCAkMjAkLCAkMTYkLCBhbmQgJDI0JCBzbWFsbCBtYXJrZXQgcmVzdGF1cmFudHMgcmVzcGVjdGl2ZWx5LiBUaGUgb3ZlcmFsbCB0cmVuZCBpcyBzaW1pbGFyIGZvciBhbGwgdGhyZWUgbWFya2V0aW5nIGNhbXBhaWducy4KCkxldHMgY29uc29saWRhdGUgdGhlc2UgdHJlbmRzIGluICoqRmlndXJlIDQuMCoqIGFuZCAqKkZpZ3VyZSA1LjAqKiBpbnRvIG9uZSBzY2F0dGVyIHBsb3QsIHRvIGJlc3QgdmlzdWFsaXplIHRoZSBkaWZmZXJlbnQgYW1vdW50IG9mIHJlc3RhdXJhbnRzIGluIGVhY2ggbWFya2V0IHNpemUgZm9yIGVhY2ggb2YgdGhlIHRocmVlIG1hcmtldGluZyBjYW1wYWlnbnMsIGFuZCBob3cgdGhvc2UgbWFya2V0cyBjb250cmlidXRlZCB0byB0aGUgbWFya2V0aW5nIGdyb3VwcyBzYWxlcy4KCmBgYHtyIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTUsIGZpZy5mdWxsd2lkdGg9VFJVRX0KbWFya2V0X2NvdW50X3NhbGVzID0gcGxvdF9seShtYXJrZXRfZGF0YSwgeSA9IG1hcmtldF9kYXRhJENvdW50LCB4ID0gbWFya2V0X2RhdGEkc2FsZXNfbWVhbiwgY29sb3IgPSB+UHJvbW90aW9uLCBjb2xvcnMgPSBjb2xvcnNfMywgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdtYXJrZXJzJywgc2l6ZXMgPSBjKDEwLCAxMDApLAogICAgICAgIG1hcmtlciA9IGxpc3Qoc3ltYm9sID0gJ2NpcmNsZScsIHNpemVtb2RlID0gJ2RpYW1ldGVyJywKICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaXN0KHdpZHRoID0gMiwgY29sb3IgPSAnYmxhY2snKSksCiAgICAgICAgdGV4dCA9IH5wYXN0ZSgnTWFya2V0aW5nIENhbXBhaWduOicsIFByb21vdGlvbiwgJzxicj5NYXJrZXQ6JywgTWFya2V0U2l6ZSwgJzxicj5SZXN0YXVyYW50IENvdW50OicsIENvdW50LCAnPGJyPlRvdGFsIFNhbGVzOicsIHNhbGVzX3RvdGFsKSkgJT4lCmxheW91dCh4YXhpcyA9IGxpc3QodGl0bGUgPSAnTWVhbiBTYWxlcyAoaW4gdGhvdXNhbmRzKScsCiAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSBjKDAsIDEwMCksCiAgICAgICAgICAgICAgICAgICAgemVyb2xpbmV3aWR0aCA9IDIsCiAgICAgICAgICAgICAgICAgICAgdGlja3dpZHRoID0gMS41LAogICAgICAgICAgICAgICAgICAgIHRpY2tsZW4gPSA1LAogICAgICAgICAgICAgICAgICAgIHRpY2twcmVmaXg9IiQiLAogICAgICAgICAgICAgICAgICAgIGdyaWR3aWR0aCA9IDIpLAogICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gJ1Jlc3RhdXJhbnQgQ291bnQnLAogICAgICAgICAgICAgICAgICAgIHJhbmdlID0gYygwLCAxNTApLAogICAgICAgICAgICAgICAgICAgIHplcm9saW5ld2lkdGggPSAyLAogICAgICAgICAgICAgICAgICAgIHRpY2t3aWR0aCA9IDEuNSwKICAgICAgICAgICAgICAgICAgICB0aWNrbGVuID0gNSwKICAgICAgICAgICAgICAgICAgICBncmlkd2l0aCA9IDIpKQoKbWFya2V0X2NvdW50X3NhbGVzCmBgYAoKKioqRmlndXJlIDYuMDoqKiBTY2F0dGVyIHBsb3Qgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTWVhbiBTYWxlcyAoeCkgYW5kIFJlc3RhdXJhbnQgQ291bnQgKHkpIGZvciBhbGwgcmVzdGF1cmFudHMgY29uZHVjdGluZyBtYXJrZXRpbmcgY2FtcGFpZ25zIGZvciBuZXcgbWVudSBpdGVtcy4gQWRkaXRpb25hbGx5LCBpZiB5b3UgaG92ZXIgb3ZlciBlYWNoIHBvaW50IHRoZSBUb3RhbCBTYWxlcyBvZiBlYWNoIHN1YiBncm91cCBpcyBsaXN0ZWQuKgoKPGJyLz4KClRoZSBiaWcgdGFrZSBhd2F5IGZyb20gKipGaWd1cmUgNi4wKiogaXMgdGhhdCAqKlByb21vdGlvbiAyIGhhZCB0aGUgbW9zdCBsYXJnZSBtYXJrZXQgcmVzdGF1cmFudHMsIGJ1dCB0aGUgbG93ZXN0IHRvdGFsIGxhcmdlIG1hcmtldCBzYWxlcyAoKip0aGUgdG90YWwgc2FsZXMgY2FuIGJlIHNlZW4gaWYgeW91IGhvdmVyIG92ZXIgdGhlIGRhdGEgcG9pbnQgaW4gKipGaWd1cmUgNi4wKiopLiBJbiBmYWN0LGFsbCBvZiBQcm9tb3Rpb24gMidzIHJlc3RhdXJhbnRzLCBubyBtYXR0ZXIgdGhlIG1hcmtldCBzaXplLCB1bmRlci1wZXJmb3JtZWQsIGJ1dCBQcm9tb3Rpb24gMidzIGxhcmdlIG1hcmtldCByZXN0YXVyYW50cyB3ZXJlIHRoZSBtb3N0IHNpZ25pZmljYW50IHVuZGVyLXBlcmZvcm1pbmcgbWFya2V0IGZvciB0aGUgUHJvbW90aW9uIDIgY29ob3J0LiAqKkZpZ3VyZSA2LjAqKiBpZGVudGlmaWVzIHRoZSByZWFzb24gUHJvbW90aW9uIDIgaGFzIHRoZSBsb3dlc3QgbWVhbiBzYWxlcywgYnV0IGFsc28gc2hvd3MgdGhhdCBsYXJnZSBtYXJrZXQgcmVzdGF1cmFudHMgdW5kZXItcGVyZm9ybWVkIG1vcmUgdGhhbiBQcm9tb3Rpb24gMidzIHNtYWxsIGFuZCBtZWRpdW0gbWFya2V0IHJlc3RhdXJhbnRzLgoKQW5zd2VyaW5nIG91ciBleHBsb3JhdG9yeSBxdWVzdGlvbiwgdGhlIG1hcmtldCBzaXplIHByb3BvcnRpb25zIHdlcmUgc2ltaWxhciBmb3IgZWFjaCBtYXJrZXRpbmcgY2FtcGFpZ24gZ3JvdXAsIGFuZCBlYWNoIG1hcmtldCBzaXplIGNvbnRyaWJ1dGVkIHByb3BvcnRpb25hbGl0eSBiYXNlZCBvbiB0aGVpciBtYXJrZXQgc2l6ZSB0byB0aGUgdG90YWwgc2FsZXMgb2YgdGhlIG1hcmtldGluZyBjYW1wYWlnbiBncm91cC4gVGhpcyB0cmVuZCBpcyB2aXN1YWxpemVkIGluICoqRmlndXJlIDYuMCoqLCB3aGljaCBzaG93cyB0aHJlZSBjbHVzdGVycy4gYSBzbWFsbCBtYXJrZXQgY2x1c3RlciwgYSBtZWRpdW0gbWFya2V0IGNsdXN0ZXIsIGFuZCBhIGxhcmdlIG1hcmtldCBjbHVzdGVyLiBUaGUgbWVkaXVtIG1hcmtldCBjbHVzdGVyIGhhZCB0aGUgbG93ZXN0IG1lYW4gc2FsZXMsIHdoaWxlIHRoZSBsYXJnZSBtYXJrZXQgaGFkIHRoZSBoaWdoZXN0IG1lYW4gc2FsZXMuCgo8YnIvPgoKIyMjICoqV2VlayoqCgpMYXN0bHksIGxldHMgbG9vayBhdCB0aGUgKioqV2VlayoqKiB2YXJpYWJsZSBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgbWFya2V0aW5nIGNhbXBhaWducy4gVGhlICoqKldlZWsqKiogdmFyaWFibGUgcmFuZ2VzIGZyb20gd2VlayAxIHRocm91Z2ggd2VlazQsIHRpbWUgc3RhbXBpbmcgdGhlIGZvdXIgd2Vla3Mgb2YgbWFya2V0aW5nIGNhbXBhaWduIHN0dWR5LiBTYWxlcyBhbW91bnRzIGZvciBlYWNoIHJlc3RhdXJhbnQgd2VyZSByZWNvcmRlZCBmb3IgZWFjaCBvZiB0aGUgZm91ciB3ZWVrcy4KCioqRXhwbG9yYXRvcnkgUXVlc3Rpb246KiogQXJlIHNvbWUgY2FtcGFpZ25zIHRyZW5kaW5nIGRpZmZlcmVudGx5PyBMb3cgc2FsZXMgaW4gd2VlayAxLCBhbmQgaGlnaGVyIGluIHdlZWsgND8KCmBgYHtyIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTQsIGZpZy5mdWxsd2lkdGg9VFJVRX0KIyBzdGFja2VkIGJhciBwbG90LCBwZXJjZW50CndlZWtfYmFyID0gcGxvdF9seShkYXRhLCB5PX5Qcm9tb3Rpb24sIHg9flNhbGVzSW5UaG91c2FuZHMsIGNvbG9yPX53ZWVrLCBjb2xvcnMgPSBjb2xvcnNfNCwgdHlwZSA9ICJiYXIiKSAlPiUKICBsYXlvdXQoYmFybW9kZT0ic3RhY2siKSAlPiUKICBsYXlvdXQoeWF4aXMgPSBsaXN0KHRpdGxlPSJNYXJrZXRpbmcgQ2FtcGFpZ24iLCBjYXRlZ29yeW9yZGVyID0gImFycmF5IiwgY2F0ZWdvcnlhcnJheSA9IGRhdGEkUHJvbW90aW9uLCAKICAgICAgICAgICAgICAgICAgICAgIGxpbmVjb2xvciA9ICJ3aGl0ZSIpKSAlPiUKICBsYXlvdXQoeWF4aXMgPSBsaXN0KG1pbm9yID0gbGlzdChzaG93Z3JpZCA9IEZBTFNFKSkpICU+JQogIGxheW91dCh4YXhpcyA9IGxpc3QodGl0bGU9IlRvdGFsIFNhbGVzIChpbiB0aG91c2FuZHMpIiksIGxlZ2VuZCA9IGxpc3QodGl0bGU9bGlzdCh0ZXh0PSdXZWVrJykpKQoKd2Vla19iYXIKYGBgCgoqKipGaWd1cmUgNy4wOioqIFN0YWNrZWQgYmFyIHBsb3Qgc2hvd2luZyB0aGUgZGlmZmVyZW5jZSBpbiB0b3RhbCBzYWxlcyBiZXR3ZWVuIG1hcmtldGluZyBjYW1wYWlnbnMgYW5kIHRoZSBmb3VyIHdlZWtzIG9mIHRoZSBjYW1wYWlnbi4qCgo8YnIvPgoKVGhlcmUgYXJlIG5vIGNsZWFyIGRpZmZlcmVuY2VzIGluIG1hcmtldGluZyBjYW1wYWlnbiBwZXJmb3JtYW5jZSB3ZWVrIHRvIHdlZWsgZm9yIGFueSBvZiB0aGUgdGhyZWUgcHJvbW90aW9ucy4gVGhlcmUgYXJlIG5vIHZpc2libGUgdHJlbmRzIHRoYXQgc2hvd3MgYW4gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgaW4gbWFya2V0aW5nIGNhbXBhaWduIHBlcmZvcm1hbmNlIHdlZWsgYnkgd2VlayBmb3IgYW55IHByb21vdGlvbi4gRWFjaCBwcm9tb3Rpb25zIHdlZWtseSBwZXJmb3JtYW5jZSBmcm9tIHdlZWsgMSB0aHJvdWdoIHdlZWsgNCBpcyBjb25zaXN0ZW50LCBlYWNoIHdlZWsgYWNjb3VudGluZyBmb3IgYWJvdXQgYSBxdWFydGVyIG9mIHRoZSBtb250aGx5IHNhbGVzLgoKPGJyLz4KCiMgIHsudW5udW1iZXJlZH0KCiMjIyAqKk92ZXJhbGwgQ29uY2x1c2lvbioqCgpUaGUgZGF0YSBmb3IgYWxsIHRocmVlIHVuZGVybHlpbmcgcG9wdWxhdGlvbnMsIFByb21vdGlvbiAxIHJlc3RhdXJhbnRzLCBQcm9tb3Rpb24gMiByZXN0YXVyYW50cywgYW5kIFByb21vdGlvbiAzIHJlc3RhdXJhbnRzLCBpcyBleHRyZW1lbHkgc2ltaWxhciB3aGVuIHdlIGxvb2sgYXQgKioqU2FsZXNJblRob3VzYW5kcyoqKiwgYW5kIGl0cyByZWxhdGlvbiB3aXRoIGFsbCB0aGUgcmVsZXZhbnQgdmFyaWFibGVzOiAqKipBZ2VPZlN0b3JlKioqLCAqKipNYXJrZXRTaXplKioqLCBhbmQgKioqV2VlayoqKi4gU3ltbWV0cnkgaW4gb3VyIGRhdGEgaXMgd2hhdCB3ZXJlIGFyZSBtb3N0IGNvbmNlcm5lZCBhYm91dCB3aGVuIGNvbXBhcmluZyB1bmRlcmx5aW5nIHBvcHVsYXRpb25zLCBhbmQgd2Ugb2JzZXJ2ZWQgbm8gc2lnbmlmaWNhbnQgaXJyZWd1bGFyaXRpZXMuIFdlIGNhbiBjb25maWRlbnRseSBwcm9jZWVkIHRvIGNvbXBhcmluZyB0aGUgKioqU2FsZXNJblRob3VzYW5kcyoqKiBtZWFucyBmb3IgZWFjaCBtYXJrZXRpbmcgY2FtcGFpZ24uCgo8YnIvPiA8YnIvPgoKIyMgMy4gRGVzY3JpYmUgdGhlIHN0YXRpc3RpY2FsIG1ldGhvZHMgeW91IHBsYW4gdG8gdXNlLiB7LnRhYnNldH0KCiMjIyAqKkFuYWx5c2lzIG9mIFZhcmlhbmNlIChBTk9WQSkqKgoKVGhlIGdvYWwgb2YgYSBvbmUtd2F5IGFuYWx5c2lzIG9mIHZhcmlhbmNlIChBTk9WQSkgaXMgdG8gY29tcGFyZSBtZWFucyBhY3Jvc3MgZ3JvdXBzLiBUaGVyZSBhcmUgbWFueSBwcm9jZWR1cmVzIHRvIGNvbXBhcmUgbWVhbnMgYWNyb3NzIHR3byBncm91cHMsIGJ1dCBBTk9WQSBpcyBhIHByb2NlZHVyZSB0aGF0IGV4dGVuZHMgdGhpcyBtZXRob2RvbG9neSB0byBhIHNldHRpbmcgd2hlcmUgdGhlcmUgYXJlIG1vcmUgdGhhbiB0d28gZ3JvdXBzLiBJbiBvdXIgc2NlbmFyaW8sIHdlIGhhdmUgdGhyZWUgZ3JvdXBzLCB0aGUgdGhyZWUgZGlmZmVyZW50IG1hcmtldGluZyBjYW1wYWlnbnMsIGFuZCB3ZSBhcmUgaW50ZXJlc3RpbmcgaW4gY29tcGFyaW5nIG1lYW4gc2FsZXMgb2YgbmV3IG1lbnUgaXRlbXMgYmV0d2VlbiB0aGUgdGhyZWUgY2FtcGFpZ25zLgoKSXQgaXMgaW1wb3J0YW50IHRvIHJlbWVtYmVyIHRoYXQgd2hlbiB3ZSBjb25kdWN0IGFuIEFOT1ZBIHRlc3QsIHdlIGFyZSBjb21wYXJpbmcgYWNyb3NzIHNldmVyYWwgZ3JvdXBzIHdoaWxlIGNvbnNpZGVyaW5nIGFsbCBvZiB0aGUgZGF0YSB0b2dldGhlci4gV2UgaGF2ZSB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ25zLCBpZiB3ZSBkaWQgbm90IHVzZSBhbiBBTk9WQSB0ZXN0LCB3ZSB3b3VsZCBsaWtlbHkgcmVzb3J0IHRvIHR3by1zYW1wbGUgdC10ZXN0aW5nIGRpZmZlcmVudCBjb21iaW5hdGlvbnMgb2YgdGhlIHRocmVlIG1hcmtldGluZyBjYW1wYWlnbnMuIEhvd2V2ZXIsIGNvbmNsdXNpb25zIGFyZSBvZnRlbiBkaWZmZXJlbnQgd2hlbiBhbGwgbWVhbnMgYXJlIGNvbnNpZGVyZWQgaW5zdGVhZCBvZiBqdXN0IGEgcGFpciBvZiBtZWFucy4gQU5PVkEgYWxsb3dzIHVzIHRvIHRha2UgaW50byBhY2NvdW50IGFsbCB0aHJlZSBtZWFucyBiZWZvcmUgd2UgbWFrZSBhIGNvbmNsdXNpb24uIFRoZSBkaWZmZXJlbmNlIGluIHRoZSB0ZXN0IHN0YXRpc3RpYywgJEYkLCBmcm9tIHRoZSB0ZXN0IHN0YXRpc3RpYyBvZiBhIHR3by1zYW1wbGUgdC10ZXN0IGlzIGZ1bmRhbWVudGFsIHRvIHRoaXMgaWRlYSBvZiB0YWtpbmcgaW50byBhY2NvdW50IG1vcmUgdGhhbiB0d28gbWVhbnMuIFRoZSBlcXVhdGlvbiBmb3IgdGhlIHRlc3Qgc3RhdGlzdGljIGZvciBhbiBBTk9WQSB0ZXN0IGlzIHNob3duIGJlbG93OgoKJCQKRiA9IFxmcmFje1x0ZXh0e0JldHdlZW4gR3JvdXAgVmFyaWFuY2V9fXtcdGV4dHtXaXRoaW4gR3JvdXAgVmFyaWFuY2V9fQokJAoKVGhlIGRldmlhdGlvbiBiZXR3ZWVuIGFuIGluZGl2aWR1YWwgcG9pbnQgYW5kIHRoZSByZXNwZWN0aXZlIGdyb3VwIG1lYW4gaXMgcmVwcmVzZW50YXRpdmUgb2YgdGhlICoqd2l0aGluIGdyb3VwIHZhcmlhbmNlKiouIEluIG91ciBzY2VuYXJpbywgdGhpcyBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBzYWxlcyBvZiBhbiBpbmRpdmlkdWFsIHJlc3RhdXJhbnQgd2hvIGlzIHVzaW5nIFByb21vdGlvbiAxIGFuZCB0aGUgbWVhbiBzYWxlcyBvZiBhbGwgcmVzdGF1cmFudCB3aG8gaXMgdXNpbmcgUHJvbW90aW9uIDEuIFRoZSBkZXZpYXRpb24gYmV0d2VlbiB0aGUgZ3JvdXAgbWVhbiBhbmQgdGhlIG92ZXJhbGwgbWVhbiBpcyByZXByZXNlbnRhdGl2ZSBvZiB0aGUgKipiZXR3ZWVuIGdyb3VwIHZhcmlhbmNlLioqIEluIG91ciBzY2VuYXJpbywgdGhpcyBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBQcm9tb3Rpb24gMSBtZWFuIHNhbGVzIGFuZCB0aGUgbWVhbnMgc2FsZXMgb2YgYWxsIHRocmVlIG1hcmtldGluZyBjYW1wYWlnbnMgKGFuZCB0aGUgc2FtZSBmb3IgdGhlIG90aGVyIHR3byBjYW1wYWlnbnMpLiBUaGVzZSBkZXZpYXRpb25zIGFyZSBzcXVhcmVkIGFuZCB0aGUgc3VtIG92ZXIgYWxsIHBvaW50cyBpcyB0YWtlbiB0byBvYnRhaW4gdGhlIHN1bSBvZiBzcXVhcmVzIHdpdGhpbiBhbmQgdGhlIHN1bSBvZiBzcXVhcmVzIGJldHdlZW4sIHJlc3BlY3RpdmVseS4KClRoYXQgaXMgYSBsb3Qgb2Ygd29yZHMuIFRoZSBpbXBvcnRhbnQgdGFrZSBhd2F5IGZyb20gdGhlIGFib3ZlIGRlc2NyaXB0aW9uIG9mICRGJCBpcyB0aGF0IHRoZSAqKkFOT1ZBIG1ldGhvZG9sb2d5IHRha2VzIGludG8gYWNjb3VudCB0aGUgb3ZlcmFsbCBtZWFuKiogKip3aGVuIGFuYWx5emluZyB2YXJpYW5jZSBvZiBhIGRhdGEgc2V0LioqIEFuZCBiZWNhdXNlIHRoZSBvdmVyYWxsIG1lYW4gaXMgYSBmdW5jdGlvbiBvZiBhbGwgZ3JvdXBzIGluIHRoZSBkYXRhIHNldCwgdGhlIEFOT1ZBIHRlc3QgaXMgZGlmZmVyZW50IHRoYW4gc2ltcGx5IHBlcmZvcm1pbmcgbXVsdGlwbGUgdHdvLXNhbXBsZSB0LXRlc3QsIHdoaWNoIG9ubHkgdXNlcyB0aGUgbWVhbnMgb2YgdHdvIGdyb3Vwcy4KCkEgZ29vZCBydWxlIG9mIHRodW1iIHdoZW4gY29uZHVjdGluZyBBTk9WQSB0ZXN0cyBpcyAqKmlmIHRoZSBiZXR3ZWVuIGdyb3VwIHZhcmlhbmNlIGlzIGxhcmdlIGFuZCB0aGUgd2l0aGluIGdyb3VwIHZhcmlhbmNlIGlzIHNtYWxsLCB0aGVuIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgb2Z0ZW4gcmVqZWN0ZWQqKiBpbiBmYXZvciBvZiB0aGUgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyB0aGF0IHRoZSB1bmRlcmx5aW5nIG1lYW5zIGFjcm9zcyBncm91cCBhcmUgbm90IGFsbCBlcXVhbC4gSW4gb3VyIHNhbGVzIGRhdGEsIHdlIG9ic2VydmUgdGhlIG9wcG9zaXRlLiBBcyBzZWVuIGluICoqRmlndXJlIDEuMCoqLCB0aGUgYmV0d2VlbiBncm91cCB2YXJpYWJpbGl0eSBpcyBzbWFsbCBhbmQgdGhlIHdpdGhpbiBncm91cCB2YXJpYWJpbGl0eSBpcyBsYXJnZS4gRm9sbG93aW5nIG91ciBydWxlIG9mIHRodW1iIGFib3ZlLCB3ZSBzaG91bGQgZXhwZWN0IHRvIGZhaWwgdG8gcmVqZWN0IG91ciBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGUgbWVhbiBzYWxlcyBvZiB0aGUgdGhyZWUgbWFya2V0aW5nIGNhbXBhaWducyBhcmUgZXF1YWwuIEFmdGVyIHdlIGNvbmR1Y3Qgb3VyIEFOT1ZBIHRlc3QgYmVsb3csIHdlIHdpbGwgc2VlIGlmIG91ciBoeXBvdGhlc2lzIGlzIGNvcnJlY3QuCgo8YnIvPgoKIyMjICoqVHVrZXkncyBQYWlyd2lzZSBULVRlc3RzKioKClNpbXBseSBwdXQsIHRoZSBwYWlyd2lzZSB0LXRlc3QgZm9yIGFuIEFOT1ZBIHRlc3QgYWxsb3dzIHVzIGRldGVybWluZSBiZXR3ZWVuIHdoaWNoIGdyb3VwcyB0aGUgZGlmZmVyZW5jZXMgKHdlIGRlZW1lZCBzaWduaWZpY2FudCBpbiBvdXIgQU5PVkEgdGVzdCkgbGllLiBUaGUgZXF1YXRpb24gZm9yIHRoZSB0ZXN0IHN0YXRpc3RpYyBmb3IgYSBUdWtleSdzIHBhaXJ3aXNlIHQtdGVzdCBpbiB0aGUgY29udGV4dCBvZiBhbiBBTk9WQSB0ZXN0IGlzIHNob3duIGJlbG93OgoKJCR0ID0gXGZyYWN7XGJhcnt4fV97cHJvbW8tMX0gLSBcYmFye3h9X3twcm9tby0yfX17XHNxcnR7c157Mn1fe3B9KFxmcmFjezF9e25fe3Byb21vLTF9fSArIFxmcmFjezF9e25fe3Byb21vLTJ9fSl9fSQkCgpUaGUga2V5IHRha2UgYXdheSBmcm9tIHRoaXMgZXF1YXRpb24sIGlzIHRoYXQgdGhlICR0JC1zdGF0aXN0aWMgaXMgYSBmdW5jdGlvbiBvZiB0aGUgdmFyaWFuY2UgZnJvbSB0aGUgQU5PVkEsICRzXnsyfV97cH0kLCBhcyBvcHBvc2VkIHRvIHVzaW5nIHRoZSBwb29sZWQgZXN0aW1hdGUgb2YgdGhlIHZhcmlhbmNlIGZyb20gb25seSBncm91cHMgaW52b2x2ZWQgaW4gdGhlIHBhaXJ3aXNlIHQtdGVzdC4gVGhpcyBpcyBhIHdoYXQgZGlmZmVyZW50aWF0ZXMgYSBUdWtleSdzIHBhaXJ3aXNlIHQtdGVzdHMgZm9yIEFOT1ZBIGZyb20gYSByZWd1bGFyIHR3by1zYW1wbGUgdC10ZXN0LiBJZiB3ZSBvbmx5IHVzZWQgdGhlIGRhdGEgZnJvbSBncm91cHMgd2Ugd291bGQgaGF2ZSBlbmRlZCB1cCB3aXRoIGEgc2xpZ2h0bHkgZGlmZmVyZW50IGVzdGltYXRlIG9mIHRoZSB2YXJpYW5jZSwgYW5kIHRodXMgYSBzbGlnaHRseSBkaWZmZXJlbnQgJHQkLXN0YXRpc3RpYy4gQmVjYXVzZSB3ZSAqKmFzc3VtZSB0aGF0IGFsbCBncm91cHMgaGF2ZSB0aGUgc2FtZSB2YXJpYW5jZSB3aGVuIGNvbmR1Y3RpbmcgYW4gQU5PVkEgdGVzdCwqKiB3ZSBkbyBub3Qgd2FudCB0byB1c2UgZGlmZmVyZW50IGVzdGltYXRlcyBvZiB0aGUgdmFyaWFuY2UgaW4gZWFjaCBwYWlyd2lzZSBjb21wYXJpc29uLgoKR2l2ZW4gdGhhdCB0aGUgZXN0aW1hdGUgZnJvbSBBTk9WQSBvZiB0aGUgdmFyaWFiaWxpdHkgaXMgYmFzZWQgb24gbW9yZSBpbmZvcm1hdGlvbiAobW9yZSBvYnNlcnZhdGlvbnMgYXJlIGluY2x1ZGVkKSwgaXQgd2lsbCBiZSBtb3JlIGFjY3VyYXRlIHRoYW4gdGhhdCBvYnRhaW5lZCBmcm9tIHVzaW5nIHRoZSBkYXRhIGZyb20ganVzdCB0d28gb2YgdGhlIGdyb3Vwcy4gT3VyIGVzdGltYXRlIG9mIHZhcmlhYmlsaXR5IGluIGFuIEFOT1ZBIHRlc3QsICRzXnsyfV97cH0kLCBpcyB0aGVyZWZvcmUgY2FsY3VsYXRlZCBmcm9tIGEgbGFyZ2VyIHNhbXBsZSBzaXplIChhbGwgZ3JvdXBzLCBub3QganVzdCB0aGUgZ3JvdXBzIGludm9sdmVkIGluIHRoZSBwYWlyd2lzZSB0LXRlc3QpLiBUaGlzIGVzdGltYXRlIG9mIHZhcmlhYmlsaXR5IGlzIG1vcmUgYWNjdXJhdGUsIGFuZCBpcyBvbmUgb2YgdGhlIHByaW1hcnkgYWR2YW50YWdlcyBvZiBBTk9WQSBwYWlyd2lzZSB0LXRlc3RzLgoKU29tZXRoaW5nIHRvIGtlZXAgaW4gbWluZCB3aGVuIHJ1bm5pbmcgbXVsdGlwbGUgcGFpcndpc2UgdC10ZXN0cyBpcyB0aGF0IHRoZSBtb3JlIHBhaXJ3aXNlIHRlc3RzIHdlIHJ1biB0aGUgbW9yZSBlcnJvcnMgd2UgYXJlIGxpa2VseSB0byBvYnNlcnZlIGR1ZSB0byBjaGFuY2UgYWxvbmUuIFRoZSBtb3JlIHlvdSBkbyBqdXN0IGFib3V0IGFueXRoaW5nIHRoZSBtb3JlIGxpa2VseSB5b3UgYXJlIHRvIG1ha2UgYSBtaXN0YWtlIGJlY2F1c2UgZXZlcnl0aW1lIHlvdSBkbyBzb21ldGhpbmcgeW91IGdpdmUgeW91cnNlbGYgdGhlIG9wcG9ydHVuaXR5IHRvIG1ha2UgYSBtaXN0YWtlLiBJZiB5b3UgZG8gbm90aGluZywgeW91IGNhbid0IG1ha2UgYSBtaXN0YWtlLiBJbiBvdXIgc2NlbmFyaW8sIGFuIGVycm9yIGlzIGEgKipUeXBlIEkgRXJyb3IsIGEgZmFsc2UgcG9zaXRpdmUgY29uY2x1c2lvbioqIChyZWplY3RpbmcgdGhlIG51bGwgaHlwb3RoZXNpcyB3aGVuIGluIHJlYWxpdHkgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyBpbiBmYWN0IHRydWUpLgoKSW4gb3JkZXIgdG8gcmVkdWNlIHRoZSBhbW91bnQgb2YgVHlwZSBJIEVycm9ycyB3ZSBoYXZlIHRvIG1ha2UgaXQgaGFyZGVyIGZvciB1cyB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBkdXJpbmcgb3VyIHBhaXJ3aXNlIHQtdGVzdHMuIE9uZSB3YXkgb2YgZG9pbmcgdGhpcyBpcyB0byBpbmNyZWFzZSBvdXIgY29uZmlkZW5jZSBsZXZlbCAoZGVjcmVhc2luZyAkXGFscGhhJCkuIFRoZXJlZm9yZSwgYXMgd2UgaW5jcmVhc2UgdGhlIG51bWJlciBvZiBwYWlyd2lzZSB0LXRlc3RzIHdlIHJ1biwgd2UgYWxzbyBpbmNyZWFzZSBvdXIgY29uZmlkZW5jZSBsZXZlbCBmb3IgdGhvc2UgcGFpcndpc2UgdC10ZXN0cyBpbiBvcmRlciB0byBiYWxhbmNlIG91dCBvdXIgaW5jcmVhc2luZyBjaGFuY2UgZm9yIGVycm9ycy4gVGhpcyBhbGxvd3MgdXMgdG8gKiptYWludGFpbiBhIHNwZWNpZmllZCBmYW1pbHktd2lzZSBUeXBlIEkgZXJyb3IgcmF0ZSoqLiBGYW1pbHktd2lzZSBUeXBlIEkgZXJyb3IgcmF0ZSBtZWFuaW5nIHRoZSBlcnJvciByYXRlIHdoZW4gbG9va2luZyBhdCBhbGwgcGFpcndpc2UgdC10ZXN0cywgbm90IGp1c3QgdGhlIFR5cGUgSSBlcnJvciByYXRlIG9mIGluZGl2aWR1YWwgcGFpcndpc2UgdC10ZXN0cy4KClByb2NlZHVyZXMgZm9yIGNvbnRyb2xsaW5nIHRoZSBmYW1pbHkgd2lzZSB0eXBlIEkgZXJyb3IgcmF0ZSBhdCBhIHByZS1zcGVjaWZpZWQgbGV2ZWwgYXJlIGNhbGxlZCBtdWx0aXBsZSBjb21wYXJpc29uIHByb2NlZHVyZXMuIEx1Y2tpbHkgZm9yIHVzLCB3ZSBhcmUgb25seSBjb25kdWN0aW5nIHRocmVlIHBhaXJ3aXNlIHRlc3RzLCBidXQgaW4gb3VyIEFOT1ZBIHRlc3Rpbmcgd2Ugd2lsbCBzdGlsbCB1c2UgdGhlICoqVHVrZXkgbXVsdGlwbGUgY29tcGFyaXNvbiBwcm9jZWR1cmUqKiwgYSBjb21wbGV4IHByb2NlZHVyZSB0aGF0IHJlcXVpcmVzIHN0YXRpc3RpY2FsIHNvZnR3YXJlICh3ZSB3aWxsIGJlIHVzaW5nIFIpLiBUaGlzIHdpbGwgcmVkdWNlIG91ciBUeXBlIDEgZXJyb3IgcmF0ZS4KCjxici8+CgojIyMgKipBbmFseXNpcyBvZiBDb3ZhcmlhbmNlIChBTkNPVkEpKioKCkFuYWx5c2lzIG9mIENvdmFyaWFuY2UgKEFOQ09WQSkgaXMgcmVhbGx5IGp1c3QgYSB2YXJpYXRpb24gb2YgYSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCwgYW5kIGFuIGV4dGVuc2lvbiBvZiB0aGUgQU5PVkEgbWV0aG9kb2xvZ3kuIFdlIGFyZSBzdGlsbCBpbnRlcmVzdGluZyBpbiB0aGUgZGlmZmVyZW50IGdyb3VwIG1lYW5zIGxpa2Ugd2UgYXJlIHdoZW4gZG9pbmcgQU5PVkEsIGJ1dCB3aGVuIGRvaW5nIEFOQ09WQSwgd2UgYXJlIGFkanVzdGluZyB0aG9zZSBncm91cCBtZWFucyBieSBhbm90aGVyIHZhcmlhYmxlLgoKKioqQWdlT2ZTdG9yZSoqKiBpcyB0aGlzIG5ldyB2YXJpYWJsZSB3ZSB3aWxsIGJlIGludHJvZHVjaW5nLCBhbmQgd2Ugd2FudCB0byBjcmVhdGUgYW4gQU5DT1ZBIG1vZGVsIHRvIHNlZSBob3cgdGhlIGFnZSBvZiB0aGUgcmVzdGF1cmFudHMgaW4gYSBjZXJ0YWluIHByb21vdGlvbmFsIGdyb3VwIGltcGFjdHMgc2FsZXMuIFRoZSBxdWVzdGlvbiB3ZSBhcmUgYXNraW5nIHdoZW4gY29uZHVjdGluZyBvdXIgQU5DT1ZBIHRlc3QgaXM6ICoqZG9lcyB0aGUgbWVhbiByZXN0YXVyYW50IHNhbGVzIHN0aWxsIGRpZmZlciBieSBtYXJrZXRpbmcgY2FtcGFpZ24gd2hlbiB0aGUgYWdlIG9mIHJlc3RhdXJhbnRzIGlzIHRha2VuIGludG8gYWNjb3VudD8qKgoKQm90aCBBTkNPVkEgYW5kIEFOT1ZBIHRlc3RpbmcgaW52b2x2ZSBtZWFuIGFuYWx5c2lzOyBob3dldmVyLCB0aGUgbWVhbnMgb2YgdGhlIHVuZGVybHlpbmcgcG9wdWxhdGlvbnMgYXJlIGRpZmZlcmVudC4gV2hlbiB3ZSBjb25kdWN0IGFuIEFOT1ZBIHRlc3Qgd2UgYXJlIGNvbXBhcmluZyBub24tYWRqdXN0ZWQgZ3JvdXAgbWVhbnMsIHdoZXJlIGFzIGluIGFuZCBBTkNPVkEgdGVzdCB3ZSBhcmUgY29tcGFyaW5nIGFkanVzdGVkIGdyb3VwIG1lYW5zLiBXaGVuIHdlIGNvbmR1Y3Qgb3VyIEFOT1ZBIHRlc3Rpbmcgd2Ugd2lsbCBub3QgdGFrZSBpbnRvIGFjY291bnQgKioqQWdlT2ZTdG9yZSoqKiB3aGVuIGFuYWx5emluZyBlYWNoIG1hcmtldGluZyBjYW1wYWlnbnMgbWVhbiBzYWxlcy4gSG93ZXZlciwgd2hlbiB3ZSBjb25kdWN0IG91ciBBTkNPVkEgdGVzdCwgd2UgZG8gdGFrZSBpbnRvIGFjY291bnQgKioqQWdlT2ZTdG9yZSoqKiwgYW5kIGFkanVzdCBvdXIgbWVhbnMgYWNjb3JkaW5nbHkgYmVmb3JlIGFuYWx5emluZyBtYXJrZXRpbmcgY2FtcGFpZ24gbWVhbiBzYWxlcyB2YXJpYW5jZS4gSW4gb3RoZXIgd29yZHMsIHdoZW4gd2UgYXJlIGNvbmR1Y3RpbmcgYW4gQU5DT1ZBIHRlc3QsIHdlIGZvbGxvdyB0aGUgc2FtZSBwcm9jZWR1cmFsIHN0ZXBzIG9mIGFuIEFOT1ZBIHRlc3QganVzdCB3aXRoIGFkanVzdGVkIHVuZGVybHlpbmcgcG9wdWxhdGlvbiBtZWFucy4KCiMgIHsudW5udW1iZXJlZH0KCjxici8+PGJyLz4KCiMjIDQuIFJlcG9ydCB5b3VyIHJlc3VsdHMuIHsudGFic2V0fQoKIyMjICoqQU5PVkEgR2xvYmFsKiogJEYkKiotVGVzdCoqCgoqKlRlc3QgUXVlc3Rpb246KiogRG8gbmV3IG1lbnUgaXRlbSBzYWxlcyBtZWFucyB2YXJ5IGJ5IG1hcmtldGluZyBjYW1wYWlnbj8KClNpbmNlIHdlIGhhdmUgdGhyZWUgZGlmZmVyZW50IHByb21vdGlvbnMsIHdlIHdpbGwgc3RhcnQgd2lsbCBzdGFydCBieSBkb2luZyBhbiBhbmFseXNpcyBvZiB2YXJpYW5jZSAoQU5PVkEpLCBnbG9iYWwgJGYkLXRlc3QuIElmIHRoZXJlIHdlcmUgb25seSB0d28gcHJvbW90aW9uYWwgY2FtcGFpZ25zLCB3ZSBjb3VsZCBzaW1wbHkgZG8gYSBwYWlyd2lzZSAkdCQtdGVzdCB0byBzZWUgaWYgdGhlIHR3byBncm91cHMgZGlmZmVyIGZyb20gZWFjaCBvdGhlci4gUmVhc29ucyBhcmUgZGlzY3Vzc2VkIGFib3ZlLgoKPGJyLz4KCiMjIyMjICoqU1RFUCAxOioqIFNldCB1cCB0aGUgaHlwb3RoZXNlcyBhbmQgc2VsZWN0IHRoZSBhbHBoYSBsZXZlbC4KCiRIX3swfTogXG11X3twcm9tby0xfSA9IFxtdV97cHJvbW8tMn0gPSBcbXVfe3Byb21vLTN9XHRleHR7IChBbGwgcHJvbW90aW9ucyByZXN1bHQgaW4gdGhlIHNhbWUgYW1vdW50IG9mIHNhbGVzKX0kCgokSF97YX06IFxtdV97cHJvbW8tMX0gXG5lIFxtdV97cHJvbW8tMn0gXHRleHR7IG9yIH0gXG11X3twcm9tby0yfSBcbmUgXG11X3twcm9tby0zfSBcdGV4dHsgb3IgfSBcbXVfe3Byb21vLTF9IFxuZSBcbXVfe3Byb21vLTN9XHRleHR7IChOb3QgYWxsIHByb21vdGlvbnMgcmVzdWx0IGluIHRoZSBzYW1lIGFtb3VudCBvZiBzYWxlcyl9JAoKJFxhbHBoYSA9IDAuMDUkCgo8YnIvPgoKIyMjIyMgKipTVEVQIDI6KiogU2VsZWN0IHRoZSBhcHByb3ByaWF0ZSB0ZXN0LXN0YXRpc3RpYywgJGYkLgoKJGYgPSBcZnJhY3tcdGV4dHtNZWFuIFNxdWFyZXMgQmV0d2Vlbn19e1x0ZXh0e01lYW4gU3F1YXJlcyBXaXRoaW59fSQKCjxici8+CgojIyMjIyAqKlNURVAgMzoqKiBTdGF0ZSB0aGUgZGVjaXNpb24gcnVsZS4KClVzZSBSIHRvIGZpbmQgJEZfe2stMSwgbi1rLCBcYWxwaGF9JCBhc3NvY2lhdGVkIHdpdGggYSByaWdodCBoYW5kIHRhaWwgcHJvYmFiaWxpdHkgb2YgJFxhbHBoYSA9IDAuMDUkLgoKYGBge3J9CnFmKDAuOTUsIGRmMT1rLTEsIGRmMj1uLWspCmBgYAoKUmVqZWN0ICRIX3swfTogXG11X3twcm9tby0xfSA9IFxtdV97cHJvbW8tMn0gPSBcbXVfe3Byb21vLTN9JCBpZiBlaXRoZXIgYXJlIFRydWU6CgoxLiAgJGZcZ2UgRl97MiwgNTQ2LCAwLjA1fSA9IDMuMDEkCjIuICAkcCA8IDAuMDUkCgo8YnIvPgoKIyMjIyMgKipTVEVQIDQ6KiogQ29tcHV0ZSB0aGUgdGVzdCBzdGF0aXN0aWMsICRmJCwgYW5kIGFzc29jaWF0ZWQgcC12YWx1ZSwgJHAkIHVzaW5nIGFvdigpLgoKYGBge3J9CiMgT25lLVdheSBBTk9WQQp0ZXN0XzEgPSBhb3YoZm9ybXVsYSA9IFNhbGVzSW5UaG91c2FuZHMgfiBQcm9tb3Rpb24sIGRhdGEgPSBkYXRhKTsgdGVzdF8xCnN1bW1hcnlfdGVzdF8xID0gc3VtbWFyeSh0ZXN0XzEpOyBzdW1tYXJ5X3Rlc3RfMQpgYGAKCiRmID0gMjEuOTUkCgokcCA9IDYuNyoxMF57LTEwfSBcc2ltIDAkCgo8YnIvPgoKIyMjIyMgKipTVEVQIDU6KiogU3RhdGUgeW91ciBjb25jbHVzaW9uLgoKQmVjYXVzZSAkZiA9IDIxLjk1ID4gMy4wMSA9IEZfezIsNTQ2LCAwLjA1fSQsIGFuZCAkcCA9IDYuNyoxMF57LTEwfSA8IDAuMDUgPSBcYWxwaGEkLCB3ZSByZWplY3QgdGhlJEhfezB9OiBcbXVfe3Byb21vLTF9ID0gXG11X3twcm9tby0yfSA9IFxtdV97cHJvbW8tM30kCgpXZSBoYXZlIHN1ZmZpY2llbnQgZXZpZGVuY2UgdGhhdCBhdCB0aGUgJFxhbHBoYSA9IDAuMDUkIGxldmVsIHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluIG1lYW4gc2FsZXMgYmV0d2VlbiBtYXJrZXRpbmcgY2FtcGFpZ25zLgoKVG8gYW5zd2VyIG91ciB0ZXN0IHF1ZXN0aW9uLCBzaW5jZSB0aGUgZ2xvYmFsICRmJC10ZXN0IHdhcyBzaWduaWZpY2FudCwgbmV3IG1lbnUgaXRlbXMgc2FsZXMgbWVhbnMgZG8gaW4gZmFjdCB2YXJ5IGJ5IG1hcmtldGluZyBjYW1wYWlnbi4gV2Ugbm93IHdhbnQgdG8gbG9vayBpbnRvIHRoZSBwYWlyd2lzZSBjb21wYXJpc29ucyBvZiB0aGUgc2FsZXMgbWVhbnMgZm9yIGVhY2ggcHJvbW90aW9uLgoKPGJyLz48YnIvPgoKIyMjICoqVHVrZXkncyBQYWlyd2lzZSoqICR0JCoqLVRlc3RzKiogey50YWJzZXR9CgoqKlRlc3QgUXVlc3Rpb246KiogQmV0d2VlbiB3aGljaCBtYXJrZXRpbmcgY2FtcGFpZ25zIGRvZXMgb3VyIGRpZmZlcmVuY2UgbGllPwoKT3VyIGdsb2JhbCBmLXRlc3QgaGFzIGRldGVybWluZWQgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4gbWVhbiBzYWxlcyBiZXR3ZWVuIG1hcmtldGluZyBjYW1wYWlnbnMsIHNvIHdlIHdpbGwgY29uZHVjdCBtdWx0aXBsZSBUdWtleSBQYWlyd2lzZSB0LXRlc3RzIHRvIGRldGVybWluZSB3aGljaCBtYXJrZXRpbmcgY2FtcGFpZ24ncyBtZWFuIHNhbGVzIGRpZmZlci4KClRoZSBzYW1lIFR1a2V5J3MgcGFpcndpc2UgdC10ZXN0aW5nIHByb2NlZHVyZSBzaG93biBmb3IgdGhlIGNvbXBhcmlzb24gb2YgUHJvbW90aW9uIDEgYW5kIFByb21vdGlvbiAyIG1lYW4gc2FsZXMgd2lsbCBiZSB1c2VkIGZvciBjb21wYXJpbmcgUHJvbW90aW9uIDIgYW5kIFByb21vdGlvbiAzIG1lYW4gc2FsZXMsIGFuZCBQcm9tb3Rpb24gMSBhbmQgUHJvbW90aW9uIDMgbWVhbiBzYWxlcy4KCjxici8+CgojIyMjICoqUHJvbW90aW9uIDEgLSBQcm9tb3Rpb24gMioqCgojIyMjIyAqKlNURVAgMToqKiBTZXQgdXAgdGhlIGh5cG90aGVzZXMgYW5kIHNlbGVjdCB0aGUgYWxwaGEgbGV2ZWwuCgokSF97MH06XG11X3twcm9tby0xfSA9IFxtdV97cHJvbW8tMn0kCgokSF97YX06IFxtdV97cHJvbW8tMX0gXG5lIFxtdV97cHJvbW8tMn0kCgokXGFscGhhID0gMC4wNSQKCjxici8+CgojIyMjIyAqKlNURVAgMjoqKiBTZWxlY3QgdGhlIGFwcHJvcHJpYXRlIHRlc3Qtc3RhdGlzdGljLCAkdCQuCgokdCA9IFxmcmFje1xiYXJ7eH1fe3Byb21vLTF9IC0gXGJhcnt4fV97cHJvbW8tMn19e1xzcXJ0e3NeezJ9X3twfShcZnJhY3sxfXtuX3twcm9tby0xfX0gKyBcZnJhY3sxfXtuX3twcm9tby0yfX0pfX0kCgo8YnIvPgoKIyMjIyMgKipTVEVQIDM6KiogU3RhdGUgdGhlIGRlY2lzaW9uIHJ1bGUuCgpgYGB7cn0KcXQoMC45NzUsIGRmID0gbi1rKQpgYGAKClJlamVjdCAkSF97MH06XG11X3twcm9tby0xfSA9IFxtdV97cHJvbW8tMn0kIGlmIGVpdGhlciBhcmUgVHJ1ZToKCjEuICAkdCBcZ2UgVF97bi1rLFxmcmFje1xhbHBoYX17Mn19ID0gMS45Nlx0ZXh0eyAgb3IgIH0gdCBcbGUgLVRfe24tayxcZnJhY3tcYWxwaGF9ezJ9fT0gLTEuOTYkCjIuICAkcCA8IFxmcmFje1xhbHBoYX17Mn0gPSAwLjAyNSBcdGV4dHsgKFJpZ2h0IGhhbmQgdGFpbCBwcm9iYWJpbGl0eSl9JAozLiAgJDAkIGlzIG5vdCB3aXRoaW4gdGhlIGJvdW5kcyBvZiBvdXIgY29uZmlkZW5jZSBpbnRlcnZhbC4KCjxici8+CgojIyMjIyAqKlNURVAgNDoqKiBDb21wdXRlIHRoZSAkdCQtc3RhdGlzdGljLCAkdCQsIGNvbmZpZGVuY2UgaW50ZXJ2YWwsIGFuZCBhc3NvY2lhdGVkIHAtdmFsdWUsICRwJC4KCmBgYHtyfQojIE1hbnVhbCBDYWxjdWxhdGlvbiBvZiB0X3ZhbHVlCnRfdmFsdWUgPSAobWVhbl8xIC0gbWVhbl8yKSAvIHNxcnQoKHN0ZF8xKioyL25fMSArIHN0ZF8yKioyL25fMikpOyB0X3ZhbHVlCiMgV2VsY2ggdC10ZXN0CnQudGVzdChwcm9tb18xJFNhbGVzSW5UaG91c2FuZHMsIHByb21vXzIkU2FsZXNJblRob3VzYW5kcykKCiMgVHVrZXkgQ29tcGFyaXNvbiBvZiBNZWFucwpUdWtleUhTRCh0ZXN0XzEpCiMgTm9uLUFkanVzdGVkIHAtdmFsdWVzICh3aWxsIG5vdCB1c2UganVzdCBmb3IgY2xhcml0eSkKcGFpcndpc2UudC50ZXN0KGRhdGEkU2FsZXNJblRob3VzYW5kcywgZGF0YSRQcm9tb3Rpb24sIHAuYWRqPSJub25lIikKYGBgCgokdCA9IDYuNDMkCgokXHRleHR7Q29uZmlkZW5jZSBJbnRlcnZhbCA9ICg2Ljc3LCAxNC44KX0kCgokcCA9IDQuMjkqMTBeey0xMH0gXHNpbSAwJAoKPGJyLz4KCiMjIyMjICoqU1RFUCA1OioqIFN0YXRlIHlvdXIgY29uY2x1c2lvbi4KCkJlY2F1c2UgJHAgPSA0LjI5KjEwXnstMTB9IDwgMC4wMjUgPSBcZnJhY3tcYWxwaGF9ezJ9JCwgYW5kICR0ID0gNi40MyBcZ2UgMS45NiA9IFRfezU0NSwwLjAyNX0kLCB3ZSByZWplY3QgdGhlICRIX3swfTpcbXVfe3Byb21vLTF9ID0gXG11X3twcm9tby0yfSQKClVzaW5nIHRoZSBUdWtleSBQYWlyd2lzZSBULVRlc3QsIHdlIGhhdmUgc3VmZmljaWVudCBldmlkZW5jZSB0aGF0IGF0IHRoZSAkXGFscGhhID0gMC4wNSQgbGV2ZWwgdGhhdCB0aGUgbWVhbiBzYWxlcyBvZiByZXN0YXVyYW50cyB1c2luZyBQcm9tb3Rpb24gMSwgJFxtdV97cHJvbW8tMX0gPSA1OC4xMCQsIGFuZCByZXN0YXVyYW50cyB1c2luZyBQcm9tb3Rpb24gMiwgJFxtdV97cHJvbW8tMn0gPSA0Ny4zMyQsIGFyZSBkaWZmZXJlbnQgZnJvbSBvbmUgYW5vdGhlci4gVGhlIG9ic2VydmVkIGRpZmZlcmVuY2UgaW4gbWVhbiBzYWxlcyBiZXR3ZWVuIHJlc3RhdXJhbnRzIGNvbmR1Y3RpbmcgUHJvbW90aW9uIDEgYW5kIHJlc3RhdXJhbnRzIGNvbmR1Y3RpbmcgUHJvbW90aW9uIDIgd2FzICQxMC43NyQgdGhvdXNhbmQgZG9sbGFycy4KCldlIGFyZSA5NSUgY29uZmlkZW50IHRoYXQgdGhlIHRydWUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBzYWxlcyBtZWFucyBpcyBiZXR3ZWVuICQ2Ljc3JCBhbmQgJDE0LjgkIHRob3VzYW5kIGRvbGxhcnMuIEFub3RoZXIgaW50ZXJwcmV0YXRpb24gb2Ygb3VyIG51bGwgaHlwb3RoZXNpcyBzdGF0ZXMgdGhhdCAkSF97MH06XG11X3twcm9tby0xfSAtIFxtdV97cHJvbW8tMn0gPSAwJCwgdGVzdGluZyB0byBzZWUgaWYgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIG1lYW5zIGlzIHplcm8uIFNpbmNlIGEgZGlmZmVyZW5jZSBvZiAkMCQgaXMgbm90IGluIG91ciBjb25maWRlbmNlIGludGVydmFsLCB3ZSBjYW4gYWdhaW4gcmVqZWN0IHRoZSAkSF97MH06XG11X3twcm9tby0xfSA9IFxtdV97cHJvbW8tMn0kLgoKPGJyLz4KCiMjIyMgKipQcm9tb3Rpb24gMiAtIFByb21vdGlvbiAzKioKCmBgYHtyfQp0X3ZhbHVlID0gKG1lYW5fMiAtIG1lYW5fMykgLyBzcXJ0KChzdGRfMioqMi9uXzIgKyBzdGRfMyoqMi9uXzMpKTsgdF92YWx1ZQp0LnRlc3QocHJvbW9fMyRTYWxlc0luVGhvdXNhbmRzLCBwcm9tb18yJFNhbGVzSW5UaG91c2FuZHMpCmBgYAoKQmVjYXVzZSAkcCA9IDEuNTcqMTBeey02fSA8IDAuMDI1ID0gXGZyYWN7XGFscGhhfXsyfSQsIGFuZCAkdCA9IDQuODggXGdlIDEuOTYgPSBUX3s1NDUsMC4wMjV9JCwgd2UgcmVqZWN0IHRoZSAkSF97MH06XG11X3twcm9tby0yfSA9IFxtdV97cHJvbW8tM30kCgpVc2luZyB0aGUgVHVrZXkgUGFpcndpc2UgVC1UZXN0LCB3ZSBoYXZlIHN1ZmZpY2llbnQgZXZpZGVuY2UgdGhhdCBhdCB0aGUgJFxhbHBoYSA9IDAuMDUkIGxldmVsIHRoYXQgdGhlIG1lYW4gc2FsZXMgb2YgcmVzdGF1cmFudHMgdXNpbmcgUHJvbW90aW9uIDIsICRcbXVfe3Byb21vLTJ9ID0gNDcuMzMkLCBhbmQgcmVzdGF1cmFudHMgdXNpbmcgUHJvbW90aW9uIDMsICRcbXVfe3Byb21vLTN9ID0gNTUuMzYkLCBhcmUgZGlmZmVyZW50IGZyb20gb25lIGFub3RoZXIuIFRoZSBvYnNlcnZlZCBkaWZmZXJlbmNlIGluIG1lYW4gc2FsZXMgYmV0d2VlbiByZXN0YXVyYW50cyBjb25kdWN0aW5nIFByb21vdGlvbiAyIGFuZCByZXN0YXVyYW50cyBjb25kdWN0aW5nIFByb21vdGlvbiAzIHdhcyAkLTguMDMkIHRob3VzYW5kIGRvbGxhcnMuCgpXZSBhcmUgOTUlIGNvbmZpZGVudCB0aGF0IHRoZSB0cnVlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgc2FsZXMgbWVhbnMgaXMgYmV0d2VlbiAkLTQuMTIkIGFuZCAkLTExLjk1JCB0aG91c2FuZCBkb2xsYXJzLiBBbm90aGVyIGludGVycHJldGF0aW9uIG9mIG91ciBudWxsIGh5cG90aGVzaXMgc3RhdGVzIHRoYXQgJEhfezB9OlxtdV97cHJvbW8tMn0gLSBcbXVfe3Byb21vLTN9ID0gMCQsIHRlc3RpbmcgdG8gc2VlIGlmIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBtZWFucyBpcyB6ZXJvLiBTaW5jZSBhIGRpZmZlcmVuY2Ugb2YgXCQwXCQgaXMgbm90IGluIG91ciBjb25maWRlbmNlIGludGVydmFsLCB3ZSBjYW4gYWdhaW4gcmVqZWN0IHRoZSAkSF97MH06XG11X3twcm9tby0yfSA9IFxtdV97cHJvbW8tM30kLgoKPGJyLz4KCiMjIyMgKipQcm9tb3Rpb24gMSAtIFByb21vdGlvbiAzKioKCmBgYHtyfQp0X3ZhbHVlID0gKG1lYW5fMSAtIG1lYW5fMykgLyBzcXJ0KChzdGRfMSoqMi9uXzEgKyBzdGRfMyoqMi9uXzMpKTsgdF92YWx1ZQp0LnRlc3QocHJvbW9fMSRTYWxlc0luVGhvdXNhbmRzLCBwcm9tb18zJFNhbGVzSW5UaG91c2FuZHMpCmBgYAoKQmVjYXVzZSAkcCA9IDAuMjQgPiAwLjAyNSA9IFxmcmFje1xhbHBoYX17Mn0kLCBhbmQgJHQgPSAxLjU1IDwgMS45NiA9IFRfezU0NSwwLjAyNX0kLCB3ZSBmYWlsIHRvIHJlamVjdCB0aGUgJEhfezB9OlxtdV97cHJvbW8tMX0gPSBcbXVfe3Byb21vLTN9JAoKVXNpbmcgdGhlIFR1a2V5IFBhaXJ3aXNlIFQtVGVzdCwgd2UgaGF2ZSBzdWZmaWNpZW50IGV2aWRlbmNlIHRoYXQgYXQgdGhlICRcYWxwaGEgPSAwLjA1JCBsZXZlbCB0aGF0IHRoZSBtZWFuIHNhbGVzIG9mIHJlc3RhdXJhbnRzIHVzaW5nIFByb21vdGlvbiAxLCAkXG11X3twcm9tby0xfSA9IDU4LjEwJCwgYW5kIHJlc3RhdXJhbnRzIHVzaW5nIFByb21vdGlvbiAzLCAkXG11X3twcm9tby0zfSA9IDU1LjM2JCwgYXJlIGRpZmZlcmVudCBmcm9tIG9uZSBhbm90aGVyLiBUaGUgb2JzZXJ2ZWQgZGlmZmVyZW5jZSBpbiBtZWFuIHNhbGVzIGJldHdlZW4gcmVzdGF1cmFudHMgY29uZHVjdGluZyBQcm9tb3Rpb24gMSBhbmQgcmVzdGF1cmFudHMgY29uZHVjdGluZyBQcm9tb3Rpb24gMyB3YXMgJC0yLjczJCB0aG91c2FuZCBkb2xsYXJzLgoKV2UgYXJlIDk1JSBjb25maWRlbnQgdGhhdCB0aGUgdHJ1ZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHNhbGVzIG1lYW5zIGlzIGJldHdlZW4gJC0xLjI2JCBhbmQgJDYuNzQkIHRob3VzYW5kIGRvbGxhcnMuIEFub3RoZXIgaW50ZXJwcmV0YXRpb24gb2Ygb3VyIG51bGwgaHlwb3RoZXNpcyBzdGF0ZXMgdGhhdCAkSF97MH06XG11X3twcm9tby0xfSAtIFxtdV97cHJvbW8tM30gPSAwJCwgdGVzdGluZyB0byBzZWUgaWYgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIG1lYW5zIGlzIHplcm8uIFNpbmNlIGEgZGlmZmVyZW5jZSBvZiAkMCQgaXMgaW4gb3VyIGNvbmZpZGVuY2UgaW50ZXJ2YWwsIHdlIGFsc28gZmFpbCB0byByZWplY3QgdGhlICRIX3swfTpcbXVfe3Byb21vLTF9ID0gXG11X3twcm9tby0zfSQuCgo8YnIvPgoKIyMjICoqQU5DT1ZBKioKCioqVGVzdCBRdWVzdGlvbjoqKiBEb2VzIHRoZSBtZWFuIHJlc3RhdXJhbnQgc2FsZXMgc3RpbGwgZGlmZmVyIGJ5IG1hcmtldGluZyBjYW1wYWlnbiB3aGVuIHRoZSBhZ2Ugb2YgcmVzdGF1cmFudHMgaXMgdGFrZW4gaW50byBhY2NvdW50PwoKVGhyb3VnaCBvdXIgaW52ZXN0aWdhdGlvbiBvZiBvdXIgZGF0YSBpbiBQYXJ0IDEsIHdlIGhhdmUgbm8gcmVhc29uIHRvIHN1c3BlY3QgYSBjb3JyZWxhdGlvbiBiZXR3ZWVuICoqKlNhbGVzSW5UaG91c2FuZHMqKiosIGFuZCAqKipBZ2VPZlN0b3JlKioqLCAqKipNYXJrZXRTaXplKioqLCBvciAqKipXZWVrKioqLiBIb3dldmVyLCBmb3IgY29tcGxldGVuZXNzLCBsZXRzIGxvb2sgYXQgdGhlICoqKkFnZU9mU3RvcmUqKiogdmFyaWFibGUsIGFuZCBjb25kdWN0IGEgcXVpY2sgQU5PVkEgdGVzdCB1c2luZyBSIHRvIGNvbmZpcm0gdGhhdCBpdCBoYXMgbm8gZWZmZWN0IG9uIHRoZSB2YXJpYW5jZSBpbiBtZWFuIHNhbGVzIGJldHdlZW4gbWFya2V0aW5nIGNhbXBhaWducy4KCmBgYHtyfQojIEludGVyZXN0ZWQgaW4gbWVhbiBzYWxlcywgQWRqdXN0aW5nIGZvciBBZ2UKIyBPUkRFUiBNQVRURVJTIHdoZW4geW91IHVzZSBhb3YoKQphbmNvdmFfbW9kZWwgPSBhb3YoU2FsZXNJblRob3VzYW5kcyB+IFByb21vdGlvbiArIEFnZU9mU3RvcmUsIGRhdGEgPSBkYXRhKQpgYGAKCmBgYHtyfQpBbm92YShhbmNvdmFfbW9kZWwsIHR5cGU9IklJSSIpCmBgYAoKKioqVGFibGUgNS4wOioqIEFOT1ZBIFRhYmxlIGZvciBvdXIgQU5DT1ZBIE1vZGVsIHRoYXQgdGFrZXMgaW50byBhY2NvdW50IGJvdGggbWFya2V0aW5nIGNhbXBhaWduICgqKlByb21vdGlvbioqKSBhbmQgKipBZ2VPZlN0b3JlKiouKgoKPGJyLz4KCldlIHNlZSBpbiAqKlRhYmxlIDUuMCoqIHRoYXQgKioqQWdlT2ZTdG9yZSoqKiBpcyBub3Qgc2lnbmlmaWNhbnRseSBhc3NvY2lhdGVkIHdpdGggdGhlIG1lYW4gc2FsZXMgb2YgYSByZXN0YXVyYW50IHdpdGggYSBsYXJnZSAkcCA9IDAuMzMyNiQsIHdoaWxlIHRoZSBtYXJrZXRpbmcgY2FtcGFpZ24gcmVtYWlucyB0byBiZSBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgbWVhbiBzYWxlcyB3aXRoIGEgc21hbGwgJHAgPSA1LjQ5KjEwXnstMTB9JC4gQWRkaXRpb25hbGx5LCB0aGUgJGYkLXN0YXRpc3RpYyBmb3IgdGhlIG1hcmtldGluZyBjYW1wYWlnbiB2YXJpYWJsZSBoYXMgbm90IGNoYW5nZWQsIHJlbWFpbmluZyBoaWdoIGF0IGFyb3VuZCAkMjIkLgoKVGhlcmVmb3JlLCB3ZSBkbyBub3QgaGF2ZSBzdWZmaWNpZW50IGV2aWRlbmNlIGF0IHRoZSAkXGFscGhhID0gMC4wNSQgbGV2ZWwgdGhhdCB0aGUgZGlmZmVyZW5jZSBpbiBhbW91bnQgb2Ygc2FsZXMgYmV0d2VlbiBtYXJrZXRpbmcgY2FtcGFpZ25zIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgKioqQWdlT2ZTdG9yZSoqKi4gVGhpcyBtZWFucyB0aGF0IHRoZSBtZWFuIHNhbGVzIG9mIGVhY2ggbWFya2V0aW5nIGNhbXBhaWduIHdpbGwgbm90IGNoYW5nZSBzaWduaWZpY2FudGx5IHdoZW4gd2UgdGFrZSBpbnRvIGFjY291bnQgKioqQWdlT2ZTdG9yZSoqKi4gVGhlcmVmb3JlLCB0aGVyZSBpcyBubyBuZWVkIHRvIGxvb2sgYXQgdGhlIHBhaXJ3aXNlIGNvbXBhcmlzb25zIG9mIHRoZSBzYWxlcyBudW1iZXJzIGZvciBlYWNoIHByb21vdGlvbiBhZnRlciBhZGp1c3RpbmcgZm9yICoqKkFnZU9mU3RvcmUqKiouCgojIyAgey51bm51bWJlcmVkfQoKPGJyLz4KCiMjIDUuIFN0YXRlIHlvdXIgY29uY2x1c2lvbnMgYW5kIGRpc2N1c3MgYW55IGxpbWl0YXRpb25zLiB7LnRhYnNldH0KCiMjIyAqKkNvbmNsdXNpb25zKioKCldlIGNvbmNsdWRlZCB0aGF0ICoqZ2xvYmFsbHkgdGhhdCB0aGVpciB3YXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbnQgYmV0d2VlbiBtYXJrZXRpbmcgY2FtcGFpZ25zIG1lYW4gc2FsZXMqKi4gSW4gdGhlIGNvbnRleHQgb2Ygb3VyIHF1ZXN0aW9uLCB0aGlzIGluZGljYXRlcyB0aGF0IHdlIG5lZWQgdG8gZmlndXJlIG91dCBiZXR3ZWVuIHdoaWNoIG1hcmtldGluZyBjYW1wYWlnbnMgdGhlIGRpZmZlcmVuY2UgbGllcywgc28gd2UgY2FuIGlkZW50aWZ5IHRoZSBzcGVjaWZpYyBtYXJrZXRpbmcgY2FtcGFpZ24gdGhhdCBpcyBnZW5lcmF0aW5nIHRoZSBtb3N0IHNhbGVzLgoKfCBDb21wYXJpc29uICAgICAgICB8ICR0JC1zdGF0aXN0aWMgfCAkcF97dHVrZXl9JCB2YWx1ZSB8IENvbmNsdXNpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwtLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAp8IFByb21vIDEgLSBQcm9tbyAyIHwgNi40MyAgICAgICAgICB8IDAgICAgICAgICAgICAgICAgIHwgU2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIG1lYW5zLiAgIHwKfCBQcm9tbyAyIC0gUHJvbW8gMyB8IDQuODggICAgICAgICAgfCAwLjAwMDAwNTUgICAgICAgICB8IFNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiBtZWFucy4gICB8CnwgUHJvbW8gMSAtIFByb21vIDMgfCAxLjU1ICAgICAgICAgIHwgMC4yNCAgICAgICAgICAgICAgfCBJbnNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiBtZWFucy4gfAoKKioqVGFibGUgNi4wOioqIFN1bW1hcnkgb2YgVHVrZXkncyBQYWlyd2lzZSBULVRlc3QgcmVzdWx0cy4qIDxici8+CgpXaGVuIGxvb2tpbmcgYXQgdGhlIGRpZmZlcmVuY2VzIGluIG1lYW4gc2FsZXMgYmV0d2VlbiBtYXJrZXRpbmcgY2FtcGFpZ25zLCBib3RoICoqUHJvbW90aW9uIDEgYW5kIFByb21vdGlvbiAzIHdlcmUgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgdGhhdCBQcm9tb3Rpb24gMiwgYnV0IG5vdCBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIG9uZSBhbm90aGVyLioqIEJvdGggUHJvbW90aW9uIDEgYW5kIFByb21vdGlvbiAzIGhhdmUgaGlnaGVyIG1lYW5zIHRoYW4gUHJvbW90aW9uIDIsIG1lYW5pbmcgdGhlc2UgYXJlIHRoZSB0d28gY2FtcGFpZ25zIHRoYXQgcmVzdWx0ZWQgaW4gbW9yZSBuZXcgbWVudSBpdGVtcyBzYWxlcyB0aGFuIHRoYW4gdGhlIFByb21vdGlvbiAyIG1hcmtldGluZyBjYW1wYWlnbi4gQm90aCBQcm9tb3Rpb24gMSBhbmQgUHJvbW90aW9uIDMgbWVhbiBzYWxlcyBmaWd1cmVzIHdlcmUgZGlmZmVyZW50IGZyb20gb25lIGFub3RoZXIsIGJ1dCBub3Qgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYXQgdGhlICRcYWxwaGEgPSAwLjA1JCBsZXZlbC4gVGhlcmVmb3JlLCBlaXRoZXIgdGhlIFByb21vdGlvbiAxIG9yIFByb21vdGlvbiAzIG1hcmtldGluZyBjYW1wYWlnbiBzaG91bGQgYmUgcHJlZmVycmVkIG92ZXIgdGhlIFByb21vdGlvbiAyIG1hcmtldGluZyBjYW1wYWlnbiBpbiBvcmRlciB0byBpbmNyZWFzZXMgdGhlIHRvdGFsIHNhbGVzIG9mIG5ldyBtZW51IGl0ZW1zLiBUbyBhbnN3ZXIgb3VyIHJlc2VhcmNoIHF1ZXN0aW9uLCAqKlByb21vdGlvbiAxIGFuZCBQcm9tb3Rpb24gMyBtYXJrZXRpbmcgY2FtcGFpZ25zIGFyZSBtb3N0IGxpa2VseSB0byByZXN1bHQgaW4gdGhlIGdyZWF0ZXN0IGluY3JlYXNlIGluIHNhbGVzIG9mIG5ldyBtZW51IGl0ZW1zIGZvciB0aGUgcmVzdGF1cmFudCBjaGFpbi4qKgoKYGBge3J9ClR1a2V5SFNEKHRlc3RfMSwgY29uZi5sZXZlbCA9IDAuOTkpCmBgYAoKRXZlbiBpZiB3ZSBjb25kdWN0IGEgVHVrZXkgUGFpcndpc2UgVC1UZXN0IGF0IHRoZSAkXGFscGhhID0gMC4wMSQgbGV2ZWwsIHRoZSByZXN1bHRzIGFyZSB0aGUgc2FtZSwgc28gdGhlIHJlc3RhdXJhbnQgc2hvdWxkIGZlZWwgY29uZmlkZW50IG1vdmluZyBmb3J3YXJkcyB3aXRoIGVpdGhlciBQcm9tb3Rpb24gMSBvciBQcm9tb3Rpb24gMyBtYXJrZXRpbmcgY2FtcGFpZ25zLCBhbmQgc2hvdWxkIGNvbnNpZGVyIGxvb2tpbmcgaW50byBvdGhlciBtYXJrZXRpbmcgY2FtcGFpZ24gZmFjdG9ycywgY29zdHMgb2YgdGhlIGNhbXBhaWducywgZWFzZSBvZiBpbXBsZW1lbnRhdGlvbiwgc3RheWluZyBwb3dlciwgZXRjLiB0byBkZXRlcm1pbmUgd2hpY2ggb2YgdGhlIHR3byBjYW1wYWlnbnMgdG8gaW1wbGVtZW50IGFjcm9zcyBhbGwgcmVzdGF1cmFudHMuCgpPdXIgKipBTkNPVkEgdGVzdGluZyoqIGFkanVzdGluZyBmb3IgKioqQWdlT2ZTdG9yZSoqKiBzaG93ZWQgbm8gY29ycmVsYXRpb24gYmV0d2VlbiAqKipBZ2VPZlN0b3JlKioqIGFuZCAqKipTYWxlc0luVGhvdXNhbmRzKioqIG1lYW5zIGZvciBlYWNoIG1hcmtldGluZyBjYW1wYWlnbi4gTWVhbmluZywgZXZlbiB3aGVuICoqKkFnZU9mU3RvcmUqKiogd2FzIHRha2VuIGludG8gYWNjb3VudCwgd2UgZGlkIG5vdCBjaGFuZ2Ugb3VyIGNvbmNsdXNpb24gZnJvbSBvdXIgb3JpZ2luYWwgQU5PVkEgdGVzdCwgYW5kIG1haW50YWluIHRoYXQgYXQgdGhlICRcYWxwaGEgPSAwLjA1JCBsZXZlbCwgbWVhbiBzYWxlcyBkaWZmZXJlbmNlIGJldHdlZW4gZm9yIFByb21vdGlvbiAxLCBQcm9tb3Rpb24gMiwgYW5kIFByb21vdGlvbiAzIGFyZSBhc3NvY2lhdGVkIHdpdGggbWFya2V0aW5nIGNhbXBhaWduLgoKTGFzdGx5LCB3ZSBoYXZlIGEgdGhyZWUgdG9waWNzIHdlIHdhbnRlZCB0byBjaXJjbGUgYmFjayB1cG9uIGFmdGVyIHdlIHRlc3RlZCBvdXIgZGF0YS4gSW4gcmVnYXJkcyB0byB0aGUgMzAgc2FsZXMgb3V0bGllcnMgZm91bmQgaW4gdGhlIFByb21vdGlvbiAyIHN1YnNldCBkaXNjdXNzZWQgaW4gb3VyIGV4cGxvcmF0aW9uIG9mIHRoZSBkYXRhLCB0aGVzZSB3aWxsIGhhdmUgbm8gaW1wYWN0IG9uIG91ciBmaW5hbCBjb25jbHVzaW9ucy4gVGhlc2Ugb3V0bGllcnMgYWxsIGZhbGwgYWJvdmUgdGhlIG1lYW4sIGFuZCB0aGVyZWZvcmUgZHJhZyB0aGUgbWVhbiB1cCwgZ2l2aW5nIFByb21vdGlvbiAyIGFuIGFydGlmaWNpYWxseSBsYXJnZSBtZWFuLiBJZiB0aGVzZSBvdXRsaWVycyB3ZXJlIHJlbW92ZWQsIGFsb25nIHdpdGggdGhlIG91dGxpZXJzIGZvciB0aGUgb3RoZXIgbWFya2V0aW5nIGNhbXBhaWducywgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBQcm9tb3Rpb24gMiBzYWxlcyBtZWFuIGFuZCB0aGUgc2FsZXMgbWVhbnMgb2YgUHJvbW90aW9uIDEgYW5kIFByb21vdGlvbiAzIHdvdWxkIGJlIGV2ZW4gbW9yZSBzaWduaWZpY2FudC4gVGhlcmVmb3JlLCB3ZSBjYW4gZGlzcmVnYXJkIHRoZSBlZmZlY3Qgb2YgdGhlc2Ugb3V0bGllcnMgd2hlbiBtYWtpbmcgb3VyIGNvbmNsdXNpb24uCgpBZnRlciBjb25jbHVkaW5nIG1lYW4gc2FsZXMgZm9yIFByb21vdGlvbiAyIHRvIGJlIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGZyb20gUHJvbW90aW9uIDIgYW5kIDMsIHdlIHNob3VsZCBnaXZlIG1vcmUgY3JlZGVuY2UgdG8gb3VyIGRpc2N1c3Npb24gcmVnYXJkaW5nICoqRmlndXJlIDYuMCoqLiBBbmQgSSB3b3VsZCByZWNvbW1lbmQgdGhhdCB0aGUgcmVzdGF1cmFudCBjaGFpbiBpbnZlc3RpZ2F0ZSBQcm9tb3Rpb24gMidzIGxhcmdlIG1hcmtldCByZXN0YXVyYW50cyB0byB1bmRlcnN0YW5kIHdoeSB0aGV5IG1heSBoYXZlIHVuZGVyLXBlcmZvcm1lZC4gVGhpcyBtYXkgZ2l2ZSBjbGFyaXR5IHRvIHNvbWUgb2YgdGhlIGNhdXNlcyBvZiB0aGUgYXNzb2NpYXRpb24gd2UgZm91bmQgYmV0d2VlbiBtYXJrZXRpbmcgY2FtcGFpZ24gYW5kIG1lYW4gc2FsZXMuCgpGaW5hbGx5LCBvdXIgZGF0YSBkaWQgbm90IGZvbGxvdyB0aGUgQU5PVkEgcnVsZSBvZiB0aHVtYiB0aGF0ICoqaWYgdGhlIGJldHdlZW4gZ3JvdXAgdmFyaWFuY2UgaXMgc21hbGwgYW5kIHRoZSB3aXRoaW4gZ3JvdXAgdmFyaWFuY2UgaXMgbGFyZ2UgdGhlbiBpdCBpcyBsaWtlbHkgdGhhdCB0aGUgdW5kZXJseWluZyBtZWFucyBhcmUgYWxsIGVxdWFsLioqIERlc3BpdGUgdGhpcywgd2UgZGlkIGZpbmQgdGhlIHVuZGVybHlpbmcgbWVhbnMgd2VyZSBub3QgYWxsIGVxdWFsLCBhbmQgdGhlcmUgd2FzIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiB1bmRlcmx5aW5nIHBvcHVsYXRpb24gbWVhbnMuIFRoaXMgc2hvd3MgdGhlIGltcG9ydGFudCBvZiB0ZXN0aW5nLCBkb2luZyB0aGUgYWN0dWFsIG1hdGggKHRoYW5rIHlvdSBSKSwgZXZlbiB3aGVuIHRoZSBkYXRhIGlzIHZpc3VhbGx5IGNvbW11bmljYXRpbmcgYSBzZWVtaW5nbHkgY2xlYXIgY29uY2x1c2lvbi4KCjxici8+CgojIyMgKipBc3N1bXB0aW9ucyoqCgpJbiBvcmRlciB0byBtYWtlIGluZmVyZW5jZXMgdXNpbmcgQU5PVkEgbWV0aG9kb2xvZ3ksIHdlIGhhdmUgdG8gbWFrZSBzdXJlIHRocmVlIGNvbmRpdGlvbnMgYXJlIG1ldDoKCjEuICAqKkluZGVwZW5kZW50LCByYW5kb20gc2FtcGxlcyBmcm9tIGVhY2ggZ3JvdXAgaW4gdGhlIHBvcHVsYXRpb24uKioKCk91ciBkYXRhIHNvdXJjZSBzdGF0ZWQgdGhhdCBlYWNoIHJlc3RhdXJhbnQgaW4gdGhlIG1hcmtldGluZyBzdHVkeSB3YXMgY2hvc2VuIGF0IHJhbmRvbSBmcm9tIGFsbCBvZiB0aGUgY29tcGFuaWVzIHJlc3RhdXJhbnRzLiBGdXJ0aGVybW9yZSwgdGhlIG1hcmtldGluZyBjYW1wYWlnbiBhc3NpZ25lZCB0byBlYWNoIHJlc3RhdXJhbnQgd2FzIGFsc28gY2hvc2VuIGF0IHJhbmRvbS4gRWFjaCByZXN0YXVyYW50IHdhcyBvbmx5IHRlc3RlZCBvbmNlLCBmb3Igb25lIG1hcmtldGluZyBjYW1wYWlnbiBvdmVyIG9uZSBtb250aC4gQXNzdW1wdGlvbiAxIGlzIHRoZXJlZm9yZSBtZXQuCgoyLiAgKipPdXRjb21lIG9mIGludGVyZXN0IGluIGdyb3VwL3BvcHVsYXRpb24gaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aCB1bmtub3duIG1lYW4qKgozLiAgKipPdXRjb21lIG9mIGludGVyZXN0IGluIGVhY2ggZ3JvdXAvcG9wdWxhdGlvbiBoYXMgYSBzaW1pbGFyIHVua25vd24gc3RhbmRhcmQgZGV2aWF0aW9uKioKCkxldHMgZ3JhcGhzIHNvbWUgaGlzdG9ncmFtcyBvZiBvdXIgb3V0Y29tZSBvZiBpbnRlcmVzdCwgKioqU2FsZXNJblRob3VzYW5kcywqKiogZm9yIGVhY2ggZ3JvdXAsICoqKlByb21vdGlvbioqKiwgaW4gb3JkZXIgdG8gY2hlY2sgZm9yIG5vcm1hbGl0eSBhbmQgdmFyaWFuY2Ugc2ltaWxhcml0eS4KCmBgYHtyfQojIERpc3RyaWJ1dGlvbnMKIyMgUHJvbW90aW9uIDEgKENvZGUgZm9yIFByb21vdGlvbiAyIGFuZCAzIGFyZSBpZGVudGljYWwsIGJ1dCBoaWRkZW4pCmJyZWFrcyA9IHNlcShmcm9tID0gMjAsIHRvID0gMTAwLCBieT0yKQoKcHJvbW9fMV9oaXN0ID0gZ2dwbG90KHByb21vXzEsIGFlcyh4PVNhbGVzSW5UaG91c2FuZHMpKSArIAogIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pLCBicmVha3MgPSBicmVha3MsIGNvbG9yPSdncmF5ODAnLCBmaWxsPSJncmF5ODAiKSArIAogIGdndGl0bGUoJ1Byb21vdGlvbiAxIFNhbGVzIERlbnNpdHkgSGlzdHJvZ3JhbScpICsKICB4bGFiKCJTYWxlcyAoaW4gdGhvdXNhbmRzKSIpICsKICB5bGFiKCJEZW5zaXR5IikgKyAKICBnZW9tX2RlbnNpdHkoY29sb3IgPSAiYmxhY2siLCBmaWxsPWNvbG9yc180WzFdLCAgYWxwaGE9MC41KSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1lYW4ocHJvbW9fMSRTYWxlc0luVGhvdXNhbmRzKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yPSdkYXJrYmx1ZScsIHNpemUgPSAwLjgpICsKICBhbm5vdGF0ZSgidGV4dCIsY29sb3I9J2RhcmtibHVlJywgc2l6ZSA9IDMsIHg9bWVhbihwcm9tb18xJFNhbGVzSW5UaG91c2FuZHMpKzEuMjUsIHk9MC4wMDc1LCAKICAgICAgICAgIGxhYmVsPSBwYXN0ZSgiTWVhbiBTYWxlcyA9Iiwgcm91bmQobWVhbihwcm9tb18xJFNhbGVzSW5UaG91c2FuZHMpLCAyKSksIGFuZ2xlPTkwKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvcj0iZ3JheTkwIiksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoY29sb3I9ImdyYXk5NCIpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JheTkwIiwgc2l6ZSA9MC41KSkgKwogIHRoZW1lKHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsPU5BLCBjb2xvdXIgPSAiZ3JheTkwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSkgKwogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoY29sb3I9ImdyYXk5MCIsIHNpemU9MC41KSkgKwogIHRoZW1lKGF4aXMudGlja3MubGVuZ3RoID0gdW5pdCgwLjE4LCAiY20iKSkgKwogIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JheTkwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGZhY2U9InBsYWluIiwgY29sb3I9ImJsYWNrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTgsIGFuZ2xlPTApLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGZhY2U9InBsYWluIiwgY29sb3I9ImJsYWNrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTgsIGFuZ2xlPTApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJwbGFpbiIsIGNvbG9yPSJibGFjayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTEyLCBhbmdsZT0wKSkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0icGxhaW4iLCBjb2xvcj0iYmxhY2siLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT0xNCwgYW5nbGU9MCkpIAojIHByb21vXzFfaGlzdApgYGAKCmBgYHtyIHJlc3VsdHM9ImhpZGUifQojIyBQcm9tb3Rpb24gMgpwcm9tb18yX2hpc3QgPSBnZ3Bsb3QocHJvbW9fMiwgYWVzKHg9U2FsZXNJblRob3VzYW5kcykpICsgCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLiksIGJyZWFrcyA9IGJyZWFrcywgY29sb3I9J2dyYXk4MCcsIGZpbGw9ImdyYXk4MCIpICsgCiAgZ2d0aXRsZSgnUHJvbW90aW9uIDIgU2FsZXMgRGVuc2l0eSBIaXN0cm9ncmFtJykgKwogIHhsYWIoIlNhbGVzIChpbiB0aG91c2FuZHMpIikgKwogIHlsYWIoIkRlbnNpdHkiKSArIAogIGdlb21fZGVuc2l0eShjb2xvciA9ICJibGFjayIsIGZpbGw9Y29sb3JzXzRbM10sICBhbHBoYT0wLjUpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbWVhbihwcm9tb18yJFNhbGVzSW5UaG91c2FuZHMpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3I9J2RhcmtibHVlJywgc2l6ZSA9IDAuOCkgKwogIGFubm90YXRlKCJ0ZXh0Iixjb2xvcj0nZGFya2JsdWUnLCBzaXplID0gMywgeD1tZWFuKHByb21vXzIkU2FsZXNJblRob3VzYW5kcykrMS4yNSwgeT0wLjAxLCAKICAgICAgICAgIGxhYmVsPSBwYXN0ZSgiTWVhbiBTYWxlcyA9Iiwgcm91bmQobWVhbihwcm9tb18yJFNhbGVzSW5UaG91c2FuZHMpLCAyKSksIGFuZ2xlPTkwKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvcj0iZ3JheTkwIiksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoY29sb3I9ImdyYXk5NCIpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JheTkwIiwgc2l6ZSA9MC41KSkgKwogIHRoZW1lKHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsPU5BLCBjb2xvdXIgPSAiZ3JheTkwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSkgKwogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoY29sb3I9ImdyYXk5MCIsIHNpemU9MC41KSkgKwogIHRoZW1lKGF4aXMudGlja3MubGVuZ3RoID0gdW5pdCgwLjE4LCAiY20iKSkgKwogIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JheTkwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGZhY2U9InBsYWluIiwgY29sb3I9ImJsYWNrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTgsIGFuZ2xlPTApLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGZhY2U9InBsYWluIiwgY29sb3I9ImJsYWNrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTgsIGFuZ2xlPTApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJwbGFpbiIsIGNvbG9yPSJibGFjayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTEyLCBhbmdsZT0wKSkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0icGxhaW4iLCBjb2xvcj0iYmxhY2siLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT0xNCwgYW5nbGU9MCkpIAoKIyBwcm9tb18yX2hpc3QKYGBgCgpgYGB7ciByZXN1bHRzPSJoaWRlIn0KIyMgUHJvbW90aW9uIDMKcHJvbW9fM19oaXN0ID0gZ2dwbG90KHByb21vXzMsIGFlcyh4PVNhbGVzSW5UaG91c2FuZHMpKSArIAogIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pLCBicmVha3MgPSBicmVha3MsIGNvbG9yPSdncmF5ODAnLCBmaWxsPSJncmF5ODAiKSArIAogIGdndGl0bGUoJ1Byb21vdGlvbiAzIFNhbGVzIERlbnNpdHkgSGlzdHJvZ3JhbScpICsKICB4bGFiKCJTYWxlcyAoaW4gdGhvdXNhbmRzKSIpICsKICB5bGFiKCJEZW5zaXR5IikgKyAKICBnZW9tX2RlbnNpdHkoY29sb3IgPSAiYmxhY2siLCBmaWxsPWNvbG9yc180WzRdLCAgYWxwaGE9MC41KSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1lYW4ocHJvbW9fMyRTYWxlc0luVGhvdXNhbmRzKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yPSdkYXJrYmx1ZScsIHNpemUgPSAwLjgpICsKICBhbm5vdGF0ZSgidGV4dCIsY29sb3I9J2RhcmtibHVlJywgc2l6ZSA9IDMsIHg9bWVhbihwcm9tb18zJFNhbGVzSW5UaG91c2FuZHMpKzEuMjUsIHk9MC4wMSwgCiAgICAgICAgICBsYWJlbD0gcGFzdGUoIk1lYW4gU2FsZXMgPSIsIHJvdW5kKG1lYW4ocHJvbW9fMyRTYWxlc0luVGhvdXNhbmRzKSwgMikpLCBhbmdsZT05MCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3I9ImdyYXk5MCIpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG9yPSJncmF5OTQiKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImdyYXk5MCIsIHNpemUgPTAuNSkpICsKICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbD1OQSwgY29sb3VyID0gImdyYXk5MCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIikpICsKICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKGNvbG9yPSJncmF5OTAiLCBzaXplPTAuNSkpICsKICB0aGVtZShheGlzLnRpY2tzLmxlbmd0aCA9IHVuaXQoMC4xOCwgImNtIikpICsKICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImdyYXk5MCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIikpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChmYWNlPSJwbGFpbiIsIGNvbG9yPSJibGFjayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT04LCBhbmdsZT0wKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChmYWNlPSJwbGFpbiIsIGNvbG9yPSJibGFjayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT04LCBhbmdsZT0wKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0icGxhaW4iLCBjb2xvcj0iYmxhY2siLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT0xMiwgYW5nbGU9MCkpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9InBsYWluIiwgY29sb3I9ImJsYWNrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9MTQsIGFuZ2xlPTApKSAKIyBwcm9tb18zX2hpc3QKYGBgCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD05LCBmaWcuZnVsbHdpZHRoPVRSVUV9CgpncmlkLmFycmFuZ2UocHJvbW9fMV9oaXN0LCBwcm9tb18yX2hpc3QsIHByb21vXzNfaGlzdCkKYGBgCgoqKipGaWd1cmUgMTAuMDoqKiBTYWxlcyBoaXN0b2dyYW1zIGZvciByZXN0YXVyYW50cyB1c2luZyBQcm9tb3Rpb24gMSAocHVycGxlKSwgUHJvbW90aW9uIDIgKGJsdWUpLCBhbmQgUHJvbW90aW9uIDMgKGdyZWVuKS4qCgo8YnIvPgoKQWxsIHRocmVlIGRlbnNpdHkgaGlzdG9ncmFtcyBhcmUgaW4gdGhlIHNhbWUgc2NhbGUsIG1ha2luZyBpdCBlYXN5IGZvciB1cyB0byBjb21wYXJlIGJvdGggbm9ybWFsaXR5IGFuZCB2YXJpYW5jZS4gV2hlbiB3ZSBleHBsb3JlZCB0aGUgZGF0YSBpbiBQYXJ0IDEsIHRoZSBkYXRhIGZvciBlYWNoIHN1YiBwb3B1bGF0aW9uIChQcm9tb3Rpb24gMSwgUHJvbW90aW9uIDIgYW5kIFByb21vdGlvbiAzKSBoYWQgdmVyeSBzaW1pbGFyIGRpc3RyaWJ1dGlvbnMgKHNlZSAqKlRhYmxlIDIuMCoqKS4gT3VyIGRlbnNpdHkgaGlzdG9ncmFtcyBpbiAqKkZpZ3VyZSAxMC4wKiogY29uZmlybSB0aGF0IHNpbWlsYXJpdHkuCgoqKkFsbCB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ25zIGRpc3RyaWJ1dGlvbnMgYXJlIGV4dHJlbWVseSBzeW1tZXRyaWMqKi4gQWx0aG91Z2ggbm9uZSBvZiB0aGUgaGlzdG9ncmFtcyBhcmUgcGVyZmVjdGx5IG5vcm1hbCwgd2hpY2ggaXMgZXhwZWN0ZWQgYXMgcGVyZmVjdCBub3JtYWxpdHkgaXMgcmFyZSBpbiBwcmFjdGljZSwgdGhleSBhcmUgc29tZXdoYXQgbm9ybWFsLiBBbGwgaGlzdG9ncmFtcyBoYXZlIG9uZSBtYWpvciBwZWFrIGFyb3VuZCAkNTMkIHRob3VzYW5kIGRvbGxhcnMsIGFuZCBhIHNlY29uZCBtaW5vciBwZWFrIGF0IGFyb3VuZCAkODAkIHRob3VzYW5kIGRvbGxhcnMuIEFsbCBoaXN0b2dyYW1zIHNrZXcgcmlnaHQgd2hpY2ggaXMgZXhwZWN0ZWQgZm9yIG1vc3QgbW9uZXRhcnkgZGlzdHJpYnV0aW9ucy4gVGhlIGRldmlhdGlvbiBmcm9tIG5vcm1hbGl0eSBpcyBub3Qgc2V2ZXJlIGVub3VnaCB0byB3YXJyYW50IGNvbmNlcm4gZm9yIGEgY291cGxlIHJlYXNvbnMuIEZpcnN0bHksIEFOT1ZBIHRlc3RpbmcgaXMgdmVyeSByb2J1c3QgZXNwZWNpYWxseSB3aGVuIHdlIGFyZSB1c2luZyBhIGxhcmdlIHNhbXBsZSBzaXplIG9mICQ1ODgkIHJlc3RhdXJhbnRzLiBTZWNvbmRseSwgdGhlIGRldmlhdGlvbnMgZnJvbSBub3JtYWxpdHkgYXJlIHNpbWlsYXIgYmV0d2VlbiB0aGUgdW5kZXJseWluZyBwb3B1bGF0aW9ucy4KCkFsbCB0aHJlZSBtYXJrZXRpbmcgY2FtcGFpZ25zIHNob3cgdmVyeSBzaW1pbGFyIHZhcmlhbmNlIGZvciAqKipTYWxlc0luVGhvdXNhbmRzKioqIGF0IGFyb3VuZCAkMTYuNzUkLiBWaXN1YWxseSwgYWxsIHRocmVlIGRpc3RyaWJ1dGlvbnMgbG9vayB2ZXJ5IHNpbWlsYXIgaW4gd2lkdGgsIGluZGljYXRpbmcgc2ltaWxhciB2YXJpYW5jZSBhbW9uZyB0aGUgdGhyZWUgbWFya2V0aW5nIGNhbXBhaWducyBzYWxlcy4gQWNjb3JkaW5nIHRvIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0sIGFzIG91ciBzYW1wbGUgc2l6ZSBpbmNyZWFzZXMsIG91ciB2YXJpYW5jZSBkZWNyZWFzZXMuIEJlY2F1c2UgZWFjaCBtYXJrZXRpbmcgY2FtcGFpZ24gcG9wdWxhdGlvbiBoYXMgYXJvdW5kICQxNzAkIHJlc3RhdXJhbnRzIGVhY2gsIG91ciBzeW1tZXRyaWMgdmFyaWFuY2UgY2FuIGJlIHBhcnRseSBhdHRyaWJ1dGVkIHRvIHRoZSByYXRoZXIgbGFyZ2UsIGVxdWFsbHkgcHJvcG9ydGlvbmVkIHVuZGVybHlpbmcgcG9wdWxhdGlvbiBzaXplcy4gSWYgd2UgaGFkIG9uZSB1bmRlcmx5aW5nIHBvcHVsYXRpb24gd2l0aCBhIGRpc3Byb3BvcnRpb25hdGVseSBzbWFsbCBwb3B1bGF0aW9uIHNpemUsIHNheSBQcm9tb3Rpb24gMSBoYWQgJDMwJCByZXN0YXVyYW50cyBpbnN0ZWFkIG9mICQxNzIkLCB3ZSB3b3VsZCBsaWtlbHkgc2VlIGEgdmFyaWFuY2UgdGhhdCB3YXMgbm90IHNpbWlsYXIgdG8gdGhlIG90aGVyIHVuZGVybHlpbmcgcG9wdWxhdGlvbnMuIEx1Y2tpbHkgdGhpcyBpcyBub3QgdGhlIGNhc2UuIFRoZSBnZW5lcmFsICoqcnVsZSBvZiB0aHVtYioqIHVzZWQgaW4gcHJhY3RpY2UgdG8gY2hlY2sgZm9yIHZhcmlhbmNlIHNpbWlsYXJpdHkgaXMgdGhhdCAqKnRoZSBsYXJnZXN0IHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24gc2hvdWxkIGJlIG5vIG1vcmUgdGhhbiB0d2ljZSBhcyBsYXJnZSBhcyB0aGUgc21hbGxlc3Qgc2FtcGxlIHN0YW5kYXJkIGRldmlhdGlvbi4qKiBPdXIgZGF0YSBmb2xsb3dzIHRoaXMgcnVsZS4KCkluIGNvbmNsdXNpb24sIGJvdGggYWxsIHRocmVlIGFzc3VtcHRpb25zIGFyZSBtZXQuCgo8YnIvPgoKIyMjICoqTGltaXRhdGlvbnMqKgoKRnJvbSBvdXIgZXhwbG9yYXRpb24gb2YgdGhlIGRhdGEsIHRoZSBvbmx5IHZhcmlhYmxlIHdpdGggYXNzb2NpYXRpb24gdG8gYSByZXN0YXVyYW50J3MgKioqU2FsZXNJblRob3VzYW5kcyoqKiB3YXMgdGhlIG1hcmtldGluZyBjYW1wYWlnbmVkIHVzZWQsICoqKkFnZU9mU3RvcmUqKiogd2FzIHNob3duIHRvIGhhdmUgbm8gY29ycmVsYXRpb24gaW4gb3VyIEFOQ09WQSB0ZXN0IGFuZCB3aGVuIHdlIGRpZCBhIHNpbXBsZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBjYWxjdWxhdGlvbi4gSG93ZXZlciwgVGhlcmUgbWF5IGJlICoqbHVya2luZyB2YXJpYWJsZXMqKiB0aGF0IGhhdmUgYSBzdHJvbmcgaW5mbHVlbmNlIG9uIGEgcmVzdGF1cmFudCdzICoqKlNhbGVzSW5UaG91c2FuZHMqKiogdGhhdCB3ZXJlIG5vdCBtZWFzdXJlZCBieSB0aGUgY29tcGFueSBpbiBvdXIgc3R1ZHkuIEFsdGhvdWdoICoqKlNhbGVzSW5UaG91c2FuZHMqKiogYW5kIFByb21vdGlvbiBhcmUgYXNzb2NpYXRlZCwgaXQgaXMgaGlnaGx5IGxpa2VseSB0aGF0IHRoZSBtYXJrZXRpbmcgY2FtcGFpZ24gaXMgbm90IHRoZSBvbmx5IHZhcmlhYmxlIHRoYXQgaXMgcmVzcG9uc2libGUgZm9yIGRpZmZlcmVuY2VzIGluIHNhbGVzIGZpZ3VyZXMuCgpGb3IgZXhhbXBsZSwgbWF5YmUgdGhlIGxvd2VyIHNhbGVzIG9ic2VydmVkIGluIHdhcyBkdWUgdG8gdGhhdCB1bmRlcmx5aW5nIHBvcHVsYXRpb24gaGF2aW5nIG1vcmUgcmVzdGF1cmFudHMgaW4gcG9vcmVyIGFyZWFzIHdpdGggcGVvcGxlIHdobyBjYW5ub3QgYWZmb3JkIHRvIGVhdCBvdXQsIG9yIG1heWJlIGFmZmx1ZW50IGFyZWEgdGhhdCBkb24ndCBlYXQgYXQgdGhlIHJlc3RhdXJhbnQgb2Z0ZW4uIFRvIGNvbnRpbnVlLCBtYXliZSB0aGUgbWFya2V0IGRlbW9ncmFwaGljcyBvZiB0aGUgdW5kZXJseWluZyBwb3B1bGF0aW9ucyBhcmUgZGlmZmVyZW50LiBJZiBQcm9tb3Rpb24gMiB3YXMgYSBkaWdpdGFsIG1hcmtldGluZyBjYW1wYWlnbiBhbmQgdGhlIFByb21vdGlvbiAyJ3MgbWFya2V0IGRlbW9ncmFwaGljcyBza2V3ZWQgb2xkZXIgdGhhbiB0aGUgUHJvbW90aW9uIDEgYW5kIFByb21vdGlvbiAyIG1hcmtldHMsIHRoYXQgZGVtb2dyYXBoaWMgZGlmZmVyZW5jZSBtYXkgaGF2ZSBjYXVzZWQgdGhlIGRlY3JlYXNlIGluIHRoZSBlZmZlY3RpdmVuZXNzIG9mIHRoZSBtYXJrZXRpbmcgY2FtcGFpZ24sIG5vdCB0aGUgY2FtcGFpZ24gaXRzZWxmLiBUaGVyZSBhcmUgbWFueSBsdXJraW5nIHZhcmlhYmxlcywgYW5kIG5lYXIgaW1wb3NzaWJsZSB0byBhY2NvdW50IGZvciBhbGwgb2YgdGhlbS4KCklmIHRpbWUgYW5kIGNhcGl0YWwgd2VyZSBpbmNvbnNlcXVlbnRpYWwsIG9uZSB3YXkgaW4gd2hpY2ggdGhlIGNvbXBhbnkgY291bGQgdmV0IG91ciBjb25jbHVzaW9ucyB3b3VsZCBiZSB0byBzd2l0Y2ggdGhlIG1hcmtldGluZyBjYW1wYWlnbnMgZWFjaCByZXN0YXVyYW50IGNvaG9ydCB1c2VzIGFuZCByZWdhdGhlciBzYWxlcyBkYXRhLiBGb3IgaW5zdGFuY2UsIGFsbCByZXN0YXVyYW50cyB0aGF0IHVzZWQgUHJvbW90aW9uIDEgd2lsbCB1c2UgUHJvbW90aW9uIDIsIFByb21vdGlvbiAyIHdpbGwgdXNlIFByb21vdGlvbiAzLCBhbmQgUHJvbW90aW9uIDMgd2lsbCB1c2UgUHJvbW90aW9uIDEuIElmIG91ciBjb25jbHVzaW9uIHRoYXQgUHJvbW90aW9uIDIgbWFya2V0aW5nIGNhbXBhaWduIHdhcyBsZWFzdCBlZmZlY3RpdmUgYXQgaW5jcmVhc2luZyBzYWxlIGhvbGRzLCB3ZSB3b3VsZCBiZSBtb3JlIGNvbmZpZGVuY2UgaW4gdGhlIGVmZmVjdCBvZiB0aGUgbWFya2V0aW5nIGNhbXBhaWduIG9uIHNhbGVzLiBFdmVuIHRob3VnaCB0aGlzIG1heSBhbnN3ZXIgc29tZSBvZiBvdXIgcXVlc3Rpb25zIGFib3V0IGRlbW9ncmFwaGljIGRpZmZlcmVuY2VzIGRpc2N1c3NlZCBhYm92ZSwgd2UgY2FuIG5ldmVyIGFjY291bnQgZm9yIGV2ZXJ5IGx1cmtpbmcgdmFyaWFibGUsIGFuZCB3ZSBjYW4gbmV2ZXIgYmUgZnVsbHkgY2VydGFpbiBhYm91dCBjYXVzYXRpb24sIG9ubHkgc3RyZW5ndGggb2YgYXNzb2NpYXRpb24uIFdlIHdvdWxkIG5lZWQgdG8gZGVzaWduIGFuZCBjb25kdWN0IG1hbnkgbW9yZSBzdHVkaWVzIHRvIHN1Z2dlc3QgY2F1c2F0aW9uLgoKIyMgIHsudW5udW1iZXJlZH0KCjxici8+PGJyLz48YnIvPgo=